温馨提示×

ubuntu readdir如何正确使用

小樊
34
2026-09-18 18:21:58
栏目: 智能运维

在 Ubuntu(Linux)下,readdir 通常是指 POSIX 目录读取函数 readdir(),用于遍历目录中的文件和子目录。下面从基本用法、示例代码、常见错误、替代方案几个方面说明如何“正确使用”。


一、readdir 是什么

readdir<dirent.h> 提供的函数,用于逐个读取目录项

#include <dirent.h>

struct dirent *readdir(DIR *dirp);
  • DIR*:目录流(由 opendir() 返回)
  • 返回值:
    • 成功:指向 struct dirent 的指针
    • 失败 / 读到结尾:返回 NULL

⚠️ readdir 不是线程安全的(线程安全版本是 readdir_r,但已不推荐)


二、基本使用流程(正确姿势)

1️⃣ 标准用法步骤

opendir()   → 打开目录
readdir()   → 循环读取
closedir()  → 关闭目录

2️⃣ 完整示例(C 语言)

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

int main(int argc, char *argv[]) {
    const char *path = ".";
    DIR *dir = opendir(path);
    if (dir == NULL) {
        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[];  // 文件名
};

d_type 常见值

含义
DT_REG 普通文件
DT_DIR 目录
DT_LNK 符号链接
DT_UNKNOWN 未知(需 stat)

示例:只列目录

if (entry->d_type == DT_DIR) {
    printf("[DIR] %s\n", entry->d_name);
}

四、常见错误 & 正确写法

❌ 错误 1:不检查 opendir 返回值

DIR *dir = opendir(path); // 可能 NULL

✅ 必须检查


❌ 错误 2:用 errno 判断 readdir 是否失败

errno = 0;
entry = readdir(dir);
if (entry == NULL && errno != 0) {
    // 错误
}

✅ 正确(但很多人漏)


❌ 错误 3:误以为 readdir 会排序

  • readdir 不保证顺序
  • 如需排序,自己 qsort

❌ 错误 4:递归遍历不处理 ...

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 *entry;
    while ((entry = readdir(dir))) {
        if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
            continue;

        char full[1024];
        snprintf(full, sizeof(full), "%s/%s", path, entry->d_name);

        if (entry->d_type == DT_DIR) {
            printf("DIR: %s\n", full);
            list_dir(full);
        } else {
            printf("FILE: %s\n", full);
        }
    }
    closedir(dir);
}

六、现代替代方案(推荐)

✅ C++(C++17 起)

#include <filesystem>
for (auto &p : std::filesystem::directory_iterator(".")) {
    std::cout << p.path() << "\n";
}

✅ Shell

ls -1
find .

七、总结

✅ 正确使用 readdir 的要点:

  • opendirreaddirclosedir
  • 检查返回值
  • 不依赖顺序
  • 处理 ...
  • 需要文件属性用 stat

如果你是想问:

  • Python 的 os.readdir
  • Linux 命令 readdir
  • 内核态 readdir
  • 特定错误(如 EOVERFLOW)

可以告诉我具体场景,我可以给更针对性的示例。

0