在 Linux 下使用 readdir(或 readdir_r)读取目录“失败”,通常不是函数本身有 bug,而是使用方式或环境不符合预期。下面按常见原因系统地说明。
opendirDIR *dir = opendir("/some/path");
if (!dir) {
perror("opendir");
return;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
...
}
❌ 错误示例:
readdir(NULL); // 必然失败
✅ 检查:
opendir 返回值是否为 NULLerrno 是什么(EACCES、ENOENT 等)opendir("/tmp/nonexist_dir");
ls -ld /root
如果是:
drwx------ root root
普通用户无法 opendir
✅ 查看错误:
perror("opendir");
这是最容易误解的点。
while ((entry = readdir(dir)) != NULL) {
...
}
readdir 返回 NULL:
errno)errno = 0;
entry = readdir(dir);
if (entry == NULL) {
if (errno != 0) {
perror("readdir");
} else {
// 正常结束
}
}
readdir 不是线程安全函数
❌ 错误:
// 多个线程同时调用 readdir(dir)
✅ 正确方案:
readdir_r(已不推荐)openat + getdents例如:
opendir("/mnt/usb");
// 此时 U 盘被拔掉
readdir(dir); // 失败
常见错误:
errno = ENOENT
opendir("link_to_dir");
ENOENTEACCES✅ 可先 stat 或 realpath
某些特殊文件系统:
procsysfs可能出现:
EIOENOTDIR#include <dirent.h>
#include <errno.h>
#include <stdio.h>
int main() {
DIR *dir = opendir("/tmp");
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *entry;
errno = 0;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
if (errno != 0) {
perror("readdir");
}
closedir(dir);
return 0;
}
你可以补充:
NULL?errno?)我可以直接帮你定位代码问题。