温馨提示×

linux readdir为何报错

小樊
38
2026-09-05 18:20:18
栏目: 智能运维

在 Linux 下使用 readdir 报错,通常有下面几类原因。我按最常见 → 较少见的顺序说明,并给出排查方法


一、最常见原因

1️⃣ 目录未成功打开(DIR* 为 NULL)

readdir 必须配合 opendir 使用:

DIR *dir = opendir(path);
if (dir == NULL) {
    perror("opendir");
    return -1;
}

❌ 错误示例:

DIR *dir;
readdir(dir);   // 未初始化,直接崩或报段错误

✅ 解决:

  • 检查路径是否存在
  • 是否有读权限
  • opendir 返回值

2️⃣ 参数类型错误(传了 FILE* 或普通指针)

readdir 原型是:

struct dirent *readdir(DIR *dirp);

❌ 错误:

FILE *fp = fopen(path, "r");
readdir(fp);   // 错误类型

✅ 解决:

  • 只能用 DIR *
  • 不能用 FILE *

3️⃣ 目录被并发修改或已关闭

例如:

closedir(dir);
readdir(dir);   // 未定义行为

✅ 解决:

  • closedir 后不要再调用 readdir

二、返回 NULL 的“报错”其实是正常的

readdir 返回 NULL 的两种情况

struct dirent *entry = readdir(dir);
if (entry == NULL) {
    // 可能是:
    // 1. 目录读取结束(正常)
    // 2. 发生错误(需 errno 判断)
}

✅ 正确写法:

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

三、多线程 / 信号安全问题(高级)

readdir 不是线程安全函数

  • readdir ❌ 线程不安全
  • readdir_r ✅(已废弃)
  • readdir_r 替代方案:用 mutex 或 openat + getdents

✅ 多线程中:

pthread_mutex_lock(&dir_lock);
readdir(dir);
pthread_mutex_unlock(&dir_lock);

四、常见 errno 含义

errno 含义
ENOENT 目录不存在
EACCES 权限不足
EBADF DIR* 非法
ENOTDIR 不是目录
EMFILE / ENFILE 文件描述符耗尽

五、最小可用示例

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

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

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

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

    closedir(dir);
    return 0;
}

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

你可以贴出:

  • 报错信息(或 errno
  • 代码片段
  • 是 C / C++ / 脚本调用?

我可以直接帮你定位是哪一行的问题。

0