温馨提示×

linux中readdir函数怎么用

小樊
46
2026-08-29 07:08:29
栏目: 智能运维

在 Linux 下,readdir 一般指的是 读取目录内容 的函数,最常用的是 POSIX 标准里的 readdir(),用于遍历目录中的文件和子目录。下面从基本用法 → 示例 → 常见注意点系统地说明。


一、readdir 是什么?

readdir 用来逐个读取目录中的目录项(dirent),通常与下面这些函数配合使用:

#include <dirent.h>
#include <sys/types.h>

相关函数:

函数 作用
opendir() 打开目录
readdir() 读取目录项
closedir() 关闭目录

二、函数原型

DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);

struct dirent 常用字段

struct dirent {
    ino_t          d_ino;       // inode 号
    off_t          d_off;
    unsigned short d_reclen;
    unsigned char  d_type;       // 文件类型(可选)
    char           d_name[256];  // 文件名
};

其中 d_name 最重要,表示文件名。


三、基本使用示例(遍历目录)

示例:列出当前目录下的所有文件

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

int main() {
    DIR *dir;
    struct dirent *entry;

    dir = opendir(".");
    if (dir == NULL) {
        perror("opendir");
        return 1;
    }

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

    closedir(dir);
    return 0;
}

编译运行

gcc readdir_example.c -o readdir_example
./readdir_example

四、过滤 ...

readdir 会返回 ...,通常需要过滤:

while ((entry = readdir(dir)) != NULL) {
    if (strcmp(entry->d_name, ".") == 0 ||
        strcmp(entry->d_name, "..") == 0)
        continue;

    printf("%s\n", entry->d_name);
}

五、判断文件类型(推荐方式)

方法 1:使用 d_type(不一定全支持)

if (entry->d_type == DT_REG) {
    printf("普通文件: %s\n", entry->d_name);
} else if (entry->d_type == DT_DIR) {
    printf("目录: %s\n", entry->d_name);
}

⚠️ 注意:某些文件系统(如 NFS)d_type 可能为 DT_UNKNOWN


方法 2:使用 lstat(更可靠)

#include <sys/stat.h>
#include <string.h>

struct stat st;
char path[512];

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

if (S_ISREG(st.st_mode)) {
    printf("普通文件\n");
} else if (S_ISDIR(st.st_mode)) {
    printf("目录\n");
}

六、readdir 的特别注意点(非常重要)

1️⃣ readdir 不是线程安全的

  • readdir() 返回的是 静态缓冲区
  • 多线程请用:
readdir_r();   // 已废弃

✅ 现代推荐:

  • 单线程使用 readdir
  • 多线程各自使用独立的 DIR *

2️⃣ readdir 不会排序

返回顺序是 文件系统内部顺序(不是字母序)。

如果需要排序:

// 保存文件名 → qsort

3️⃣ readdir 只返回文件名

  • 不包含路径
  • 需要自己拼接路径

七、常见错误

❌ 忘记 closedir
❌ 直接 readdir(NULL)
❌ 假设 d_type 一定准确
❌ 使用 readdir 判断是否是目录(不可靠)


八、完整示例(判断文件类型)

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

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

    while ((ent = readdir(dir)) != NULL) {
        struct stat st;
        stat(ent->d_name, &st);

        if (S_ISDIR(st.st_mode)) {
            printf("[D] %s\n", ent->d_name);
        } else {
            printf("[F] %s\n", ent->d_name);
        }
    }

    closedir(dir);
    return 0;
}

九、总结一句话

readdir 用来遍历目录,返回的是 struct dirent,需要用 opendir 打开、closedir 关闭,文件类型判断推荐用 stat

如果你需要的是 系统调用 getdents递归遍历目录避免符号链接、或 用 C++ 实现,可以继续问我。

0