温馨提示×

linux readdir为何报错了

小樊
50
2026-10-05 14:46:17
栏目: 智能运维

readdir 在 Linux 下“报错”通常不是函数本身返回错误,而是用法或环境不对导致。下面按最常见原因帮你对照排查。


一、readdir 返回 NULL 不一定是错误

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    ...
}
  • readdir 返回 NULL 有两种情况:
    1. ✅ 目录读取结束(正常)
    2. ❌ 发生错误

如何区分?

if (entry == NULL) {
    if (errno != 0) {
        perror("readdir");
    } else {
        // 正常结束
    }
}

二、最常见的 6 个错误原因

1️⃣ 没有先用 opendir

❌ 错误:

DIR *dir;
readdir(dir); // dir 未初始化

✅ 正确:

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

2️⃣ 目录路径不对 / 权限不足

opendir 失败常见原因:

  • 路径不存在
  • 没有执行权限(x)
  • SELinux / 容器限制

检查:

ls -ld /path

3️⃣ readdir 在多线程中不安全

  • readdir 不是线程安全
  • 多线程请用:
    readdir_r(dir, entry, &result);
    
    或
    readdir64_r
    

4️⃣ 读取过程中目录被修改

比如:

  • 文件被删除
  • 目录被 rename

可能导致:

EBADF
ENOENT

5️⃣ 混用 closedir

❌ 错误:

closedir(dir);
readdir(dir); // 已关闭

6️⃣ 32/64 位或 _FILE_OFFSET_BITS 问题

老代码常见:

#define _FILE_OFFSET_BITS 64

否则大目录可能异常。


三、最小可运行示例

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

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

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

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

    closedir(dir);
    return 0;
}

四、如果你愿意,我可以更精准帮你

你可以直接贴:

  • ❌ 报错信息(perror 或 errno)
  • ❌ 代码段
  • ❌ 运行的 Linux 版本 / glibc 版本

我可以直接告诉你是哪一行、为什么错。

0 踩