温馨提示×

linux readdir怎么报错

小樊
44
2026-09-11 14:15:00
栏目: 智能运维

在 Linux 下使用 readdir(或更常见的 readdir() / readdir_r())时报错,通常不是函数“本身”报错,而是调用方式或环境不对导致返回 NULL 或崩溃。下面按常见原因给你梳理一下。


一、readdir 基本用法(先确认你用对了)

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

int main() {
    DIR *dir = opendir(".");
    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;
}

二、常见“报错”原因

1️⃣ opendir 失败(最常见)

readdir 返回 NULL,其实是 opendir 没成功。

DIR *dir = opendir("/some/path");
if (!dir) {
    perror("opendir");  // 这里才会告诉你真实错误
}

常见错误:

  • 路径不存在
  • 权限不足
  • 不是目录

2️⃣ readdir 返回 NULL 但不知道是不是错误

readdir 返回 NULL 有两种情况:

entry = readdir(dir);
if (entry == NULL) {
    if (errno != 0) {
        perror("readdir");  // 真出错
    } else {
        // 只是目录读完了
    }
}

⚠️ 注意:读目录结束是正常行为,不是错误。


3️⃣ 多线程下用 readdir(危险)

readdir 不是线程安全的。

❌ 错误示例(多线程):

readdir(dir); // 可能数据竞争

✅ 正确做法:

struct dirent entry;
struct dirent *result;
readdir_r(dir, &entry, &result);

或直接使用 readdir 但加锁。


4️⃣ 目录被中途修改

readdir 过程中:

  • 文件被删除
  • 目录被卸载

可能导致:

  • EBADF
  • ENOENT

5️⃣ 用了错误的结构体

不同系统 struct dirent 字段不同:

struct dirent {
    ino_t d_ino;
    off_t d_off;
    unsigned short d_reclen;
    unsigned char d_type;
    char d_name[256];
};

不要手动 malloc 一个 direntreaddir


6️⃣ 用了 C++ / 文件名编码问题

  • 中文路径
  • UTF-8 / GBK 混用

可能导致:

  • opendir 失败
  • readdir 乱码

三、如何快速定位错误

✅ 永远配合 perror / errno

#include <errno.h>

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

四、调试建议

strace ./your_program

可以看到:

  • openat
  • getdents
  • 真正的错误码

五、如果你愿意,可以直接贴代码

你可以把:

  • 报错信息
  • 代码片段
  • 操作系统版本

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

0