在 Linux 下使用 readdir()(或 readdir_r())读取目录时,“读取失败”通常表现为:
readdir() 返回 NULLerrno 被设置为某个错误码下面按常见原因 → 说明 → 排查方法来总结。
opendir() 失败readdir() 必须在 opendir() 成功后使用。
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
}
常见错误:
ENOENTEACCESENOTDIR✅ 排查:
ls -ld /path
即使 opendir() 成功,目录也需要读权限(r):
chmod +r /path
错误码:
EACCES✅ 检查:
namei -l /path
在以下情况 readdir() 可能行为异常:
虽然不一定“失败”,但可能:
NULL✅ 建议:
scandir() 拷贝一份对 超大目录(几十万+ 文件):
readdir() 本身不会失败错误码:
EMFILE(文件描述符耗尽)ENOMEM✅ 排查:
ulimit -n
错误码:
EIOESTALE(文件句柄失效)✅ 检查:
mount | grep path
dmesg | tail
EIOEROFS错误用法示例:
closedir(dir);
readdir(dir); // ❌ 已关闭
或:
DIR*✅ 正确做法:
DIR*readdir_r()如果:
opendir("symlink")
而符号链接指向不存在目录:
ENOENT✅ 检查:
readlink -f path
⚠️ 重要:
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
...
}
NULL 可能只是读到结尾errno✅ 正确写法:
errno = 0;
entry = readdir(dir);
if (!entry && errno != 0) {
perror("readdir");
}
readdir() vs readdir64()✅ 建议:
readdir() + _FILE_OFFSET_BITS=64| errno | 含义 |
|---|---|
| ENOENT | 目录不存在 |
| EACCES | 权限不足 |
| ENOTDIR | 不是目录 |
| EBADF | DIR 指针无效 |
| EIO | I/O 错误 |
| EMFILE | 文件描述符满 |
| ESTALE | 文件句柄失效 |
DIR *dir = opendir(path);
if (!dir) {
perror("opendir");
return;
}
errno = 0;
struct dirent *de;
while ((de = readdir(dir)) != NULL) {
printf("%s\n", de->d_name);
}
if (errno != 0) {
perror("readdir");
}
closedir(dir);
如果你愿意,可以:
我可以帮你精准定位原因。