温馨提示×

linux readdir如何配合stat

小樊
37
2026-09-14 19:15:39
栏目: 智能运维

在 Linux 下,readdir 用来遍历目录中的条目(文件名),而 stat(或 lstat)用来获取这些文件的具体信息(类型、大小、权限、时间等)。二者通常配合使用的典型流程是:

opendir → readdir → 对每个条目用 stat → 处理文件信息 → closedir


一、基本流程

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[]) {
    const char *path = argc > 1 ? argv[1] : ".";
    DIR *dir = opendir(path);
    if (!dir) {
        perror("opendir");
        return 1;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        // 跳过 . 和 ..
        if (strcmp(entry->d_name, ".") == 0 ||
            strcmp(entry->d_name, "..") == 0)
            continue;

        // 构造完整路径
        char fullpath[1024];
        snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);

        struct stat st;
        if (stat(fullpath, &st) == -1) {
            perror("stat");
            continue;
        }

        // 示例:判断文件类型
        if (S_ISREG(st.st_mode))
            printf("文件: ");
        else if (S_ISDIR(st.st_mode))
            printf("目录: ");
        else
            printf("其他: ");

        printf("%s, size=%ld\n", entry->d_name, st.st_size);
    }

    closedir(dir);
    return 0;
}

二、readdir 和 stat 的职责分工

readdir

  • 只返回:
    • 文件名 d_name
    • 文件类型(d_type不一定可靠
  • 不包含文件大小、权限、时间

stat

  • 需要完整路径
  • 返回:
    • 文件类型
    • 大小
    • 权限
    • 修改 / 访问 / 状态改变时间
    • inode 等

三、路径拼接很重要(常见坑)

⚠️ readdir 返回的只是文件名,不是路径

stat(entry->d_name, &st); // ❌ 只在当前目录有效

✅ 正确写法:

snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
stat(path, &st);

四、stat / lstat / fstat 的区别

函数 说明
stat() 跟随符号链接
lstat() 跟随符号链接(看链接本身)
fstat() 通过文件描述符获取

如果你要区分“符号链接本身”和“指向的文件”,用 lstat

lstat(fullpath, &st);
if (S_ISLNK(st.st_mode)) {
    printf("符号链接\n");
}

五、readdir 的 d_type(非必须)

有些文件系统支持:

if (entry->d_type == DT_DIR) { ... }

⚠️ 但并不是所有系统都可靠(例如某些网络文件系统),保险做法还是用 stat


六、典型应用场景

  • ls 实现
  • 递归遍历目录
  • 文件扫描 / 备份工具
  • 判断文件类型、大小、时间

如果你愿意,我可以:

  • 给你一个 递归遍历目录的例子
  • 写一个 类似 ls -l 的实现
  • 对比 C++ / Python / shell 的写法

你更想看哪一种?

0