温馨提示×

ubuntu readdir怎么捕获错误

小樊
36
2026-10-18 08:02:04
栏目: 智能运维

在 Ubuntu(Linux)下使用 C/C++ 的 readdir() 时,错误不是通过返回值区分的,而是要通过 errno 来捕获。下面详细说明。


一、readdir() 的错误处理方式

函数原型

#include <dirent.h>

struct dirent *readdir(DIR *dirp);

返回值说明

  • 成功:返回指向 struct dirent 的指针
  • 到达目录末尾:返回 NULL,且 不设置 errno
  • 发生错误:返回 NULL,且 设置 errno

⚠️ 所以:

不能只判断 readdir() == NULL,必须配合 errno


二、正确捕获错误的方式

推荐写法(最安全)

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

int main() {
    DIR *dir = opendir("/some/path");
    if (!dir) {
        perror("opendir");
        return 1;
    }

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

    if (errno != 0) {
        perror("readdir");
    }

    closedir(dir);
    return 0;
}

✅ 关键点:

  • errno = 0 在循环前
  • readdir 返回 NULL 后检查 errno
  • errno != 0 才是真正错误

三、常见错误 errno

errno 含义
EBADF dirp 不是有效的目录流
ENOENT 目录在遍历中被删除
EACCES 权限不足
ENOMEM 内存不足

四、进阶:使用 readdir_r(线程安全)

struct dirent *result;
struct dirent entry;
errno = 0;
while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
    printf("%s\n", entry.d_name);
}
if (errno != 0) {
    perror("readdir_r");
}

⚠️ readdir_r 在新 glibc 中已被标记为废弃,但老代码常见。


五、更现代的替代方案(推荐)

getline + scandir

或 C++17 std::filesystem:

#include <filesystem>
namespace fs = std::filesystem;

for (auto &p : fs::directory_iterator("/some/path")) {
    std::cout << p.path() << "\n";
}

异常即可捕获错误,比 readdir 安全很多。


六、总结

✅ Ubuntu 下 readdir 错误捕获要点:

  1. 返回 NULL 不一定出错
  2. 必须检查 errno
  3. opendir 失败用 perror
  4. 循环前 errno = 0
  5. 推荐新项目用 std::filesystem

如果你有 具体代码 或 遇到的错误现象,可以直接贴出来,我帮你分析。

0 踩