欢迎光临
我们一直在努力

Linux C 文件操作核心结构体总结:dirent /stat/ DIR / FILE /glob_t

在 Linux C 开发中,文件与目录操作是高频场景,但相关结构体繁多,容易混淆。本文对 5 个核心结构体进行系统梳理,帮助开发者快速掌握其用途与区别,避免踩坑。

我在做 Linux 嵌入式开发时,经常和这几个结构体打交道,踩过不少坑。今天我把它们的核心知识点和避坑指南整理出来,希望能帮到大家。

1. struct dirent:目录项结构

  • 定义:#include <dirent.h>

  • 作用:存储目录中单个文件的元信息(文件名、inode 号等)。

  • 典型流程:opendir() → readdir() → closedir()

  • 核心成员:

    • d_name:文件名

    • d_ino:文件 inode 号

#include <dirent.h>
#include <stdio.h>

int main() {
DIR *dir = opendir(".");
struct dirent *ent;

while ((ent = readdir(dir)) != NULL) {
printf("%s\\n", ent->d_name);
}

closedir(dir);
return 0;
}

2. struct stat:文件属性结构

  • 定义:#include <sys/stat.h>

  • 作用:获取文件的详细属性(大小、类型、权限、时间戳等)。

  • 典型函数:stat() / lstat() / fstat()

  • 核心成员:

    • st_size:文件大小(字节)

    • st_mode:文件类型与权限(需配合掩码 S_IFMT、0777 使用,例如 S_ISREG(st_mode) 判断是否为普通文件)

    • st_mtime:最后修改时间

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
struct stat st;
if (stat("test.txt", &st) == 0) {
printf("Size: %ld bytes\\n", st.st_size);
if (S_ISREG(st.st_mode)) {
printf("Regular file\\n");
}
printf("Permissions: %o\\n", st.st_mode & 0777);
} else {
perror("stat failed");
}
return 0;
}

3. DIR:目录句柄

  • 定义:#include <dirent.h>

  • 作用:代表一个已打开的目录,作为遍历目录的操作句柄。

  • 典型流程:opendir() 打开目录 → readdir() 读取目录项 → closedir() 关闭。

  • 注意:DIR 是不透明类型,内部结构由系统实现,不应直接访问。

#include <dirent.h>
#include <stdio.h>
#include <string.h>

int main() {
// 1. 打开当前目录,获取DIR句柄
DIR *dir_ptr = opendir(".");
if (dir_ptr == NULL) { // 必加错误检查,贴近实际开发
perror("opendir failed");
return 1;
}

struct dirent *ent_ptr;
// 2. 循环读取目录项,直到readdir返回NULL
while ((ent_ptr = readdir(dir_ptr)) != NULL) {
// 过滤.和..目录,避免无意义输出(实际开发常用技巧)
if (strcmp(ent_ptr->d_name, ".") == 0 || strcmp(ent_ptr->d_name, "..") == 0) {
continue;
}
printf("文件名:%s | inode号:%ld\\n", ent_ptr->d_name, ent_ptr->d_ino);
}

// 3. 关闭DIR句柄,避免资源泄漏
closedir(dir_ptr);
return 0;
}

4. FILE:文件流句柄

  • 定义:#include <stdio.h>

  • 作用:标准 C 库提供的文件操作句柄,支持缓冲 I/O。

  • 典型流程:fopen() 打开文件 → fread()/fwrite() 读写 → fclose() 关闭。

  • 与文件描述符的关系:可通过 fileno(FILE*) 获取底层文件描述符,用于更底层的操作。

#include <stdio.h>
#include <string.h>

int main() {
// 1. 打开文件(w+:读写模式,不存在则创建,存在则清空)
FILE *fp = fopen("test.txt", "w+");
if (fp == NULL) { // 必加错误检查
perror("fopen failed");
return 1;
}

// 2. 写入数据(带缓冲,实际开发常用fputs/fprintf)
const char *content = "Linux C FILE结构体示例\\n";
fputs(content, fp);

// 3. 移动文件指针到开头,准备读取
fseek(fp, 0, SEEK_SET);

// 4. 读取数据并打印
char buf[1024] = {0};
fgets(buf, sizeof(buf), fp);
printf("读取到的内容:%s", buf);

// 5. 可选:获取底层文件描述符(对接Linux系统调用)
int fd = fileno(fp);
printf("FILE对应的文件描述符:%d\\n", fd);

// 6. 关闭文件,释放缓冲+句柄
fclose(fp);
return 0;
}

5. glob_t:路径匹配结构

  • 定义:#include <glob.h>

  • 作用:用于批量匹配文件路径(如 *.c、/usr/bin/*)。

  • 典型函数:glob() 执行匹配 → globfree() 释放资源。

  • 核心成员:

    • gl_pathv:匹配到的路径数组

    • gl_pathc:匹配到的路径数量

#include <glob.h>
#include <stdio.h>

int main() {
glob_t g;
if (glob("./*.c", 0, NULL, &g) == 0) {
for (size_t i = 0; i < g.gl_pathc; i++) {
printf("%s\\n", g.gl_pathv[i]);
}
}
globfree(&g);
return 0;
}

核心区别速查表

结构体核心用途关联函数典型场景
struct dirent 存储目录项信息 readdir() 遍历目录、列出文件名
struct stat 获取文件属性 stat() / lstat() 查文件大小、类型、权限
DIR 目录操作句柄 opendir() / closedir() 打开、遍历目录
FILE 文件流操作 fopen() / fclose() 读写普通文件(带缓冲)
glob_t 批量路径匹配 glob() / globfree() 批量查找 .c 文件等

风险提示(必看)

  • 线程安全:在多线程环境中,使用 DIR 和 FILE 句柄时需要注意线程安全,避免并发读写导致数据混乱。

  • 路径安全:使用 glob() 函数时,要注意路径匹配的安全性,避免因用户输入导致的路径遍历漏洞。

  • 资源泄漏:所有打开的句柄(DIR*、FILE*)都必须在使用后正确关闭,glob_t 必须用 globfree() 释放,否则会造成资源泄漏,长期运行的程序尤其需要注意。

  • 你在 Linux C 文件操作中,还遇到过哪些结构体相关的坑?欢迎在评论区分享你的经验,我们一起交流进步。

    水平有限,欢迎大家交流指正,共同进步。

    赞(0)
    未经允许不得转载:171主机测评 » Linux C 文件操作核心结构体总结:dirent /stat/ DIR / FILE /glob_t
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址