温馨提示×

debian readdir如何正确使用

小樊
48
2026-09-07 10:11:38
栏目: 智能运维

在 Debian(以及其它 Linux 发行版)上,readdir 是 POSIX / glibc 提供的目录读取函数,常用于 C/C++ 程序中遍历目录。下面从基本概念、使用示例、常见错误、替代方案几个方面说明如何“正确使用”。


一、readdir 是什么

readdir 用于逐个读取目录中的条目(文件、子目录、符号链接等)。

相关头文件:

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

核心函数:

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

二、最小可用示例(推荐写法)

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

int main(void) {
    DIR *dir = opendir(".");
    if (!dir) {
        perror("opendir");
        return 1;
    }

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

    closedir(dir);
    return 0;
}

编译:

gcc readdir_example.c -o readdir_example

三、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_type 取值(部分)

  • DT_REG 普通文件
  • DT_DIR 目录
  • DT_LNK 符号链接

⚠️ 注意:
d_type 在某些文件系统上不可靠(如部分网络文件系统),需要类型时建议用 stat()。


四、判断文件类型(稳妥方式)

#include <sys/stat.h>

struct stat st;
char path[512];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);

if (stat(path, &st) == 0) {
    if (S_ISDIR(st.st_mode))
        printf("目录: %s\n", entry->d_name);
}

五、忽略 . 和 ..

if (strcmp(entry->d_name, ".") == 0 ||
    strcmp(entry->d_name, "..") == 0)
    continue;

六、递归遍历目录(示例思路)

void list_dir(const char *path) {
    DIR *dir = opendir(path);
    if (!dir) return;

    struct dirent *e;
    while ((e = readdir(dir))) {
        if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, ".."))
            continue;

        char full[1024];
        snprintf(full, sizeof(full), "%s/%s", path, e->d_name);
        printf("%s\n", full);

        if (e->d_type == DT_DIR)
            list_dir(full);
    }
    closedir(dir);
}

七、线程安全问题(重要)

  • readdir 不是线程安全
  • 多线程请用:
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

⚠️ 但 readdir_r 在新 glibc 中已被标记为废弃,官方建议用 readdir + 加锁。


八、readdir 与 readdir64

在 Debian 64 位系统上:

  • readdir 实际等价于 readdir64
  • 大目录 / inode 很大时无需特殊处理

九、常见错误

❌ 忘记 closedir → 文件描述符泄漏
❌ 假设 d_type 一定有效
❌ 多线程共享 DIR*
❌ 用 readdir 后直接修改 d_name


十、更现代的替代方案(C++ / 新项目)

  • C++17:std::filesystem
  • C:使用 nftw()(遍历整个目录树)
  • Shell:直接用 find(非编程场景)

如果你有具体使用场景(例如:遍历大目录、过滤文件、递归删除、性能问题),可以告诉我,我可以给你更针对性的示例。

0 踩