在 Linux 下使用 readdir()(或 readdir_r())遍历目录时,“漏读”通常不是 readdir() 本身的 bug,而是使用方式或并发环境导致的问题。下面从原因 → 解决方案 → 示例代码系统说明。
✅ 这是 POSIX 允许的行为,不是 bug
opendir() + readdir() 时目录被替换rm -rf dir && mv newdir dirDIR* 仍指向旧 inodeDIR*readdir() 不是线程安全的DIR* 会互相干扰NULL最推荐方案
readdir() 收集文件名while ((ent = readdir(dir))) {
names.push_back(ent->d_name);
}
closedir(dir);
// 再处理 names
fdopendir() + 文件锁(高级)防止别人改目录:
int fd = open(path, O_RDONLY | O_DIRECTORY);
flock(fd, LOCK_SH);
DIR *dir = fdopendir(fd);
注意:只对其他遵守锁的进程有效
readdir_r()(线程安全)(已不推荐,但可用)
struct dirent entry;
struct dirent *result;
while (readdir_r(dir, &entry, &result) == 0 && result) {
// 使用 entry.d_name
}
⚠️ glibc 2.34+ 已标记 readdir_r 为 deprecated
errno = 0;
while ((ent = readdir(dir)) != NULL) {
// 正常处理
}
if (errno != 0) {
perror("readdir");
}
否则错误会被误认为“遍历结束”
inotifyreaddir() 不适合“持续监听”inotify 监听创建/删除事件readdir() 本身不会漏可选替代:
getdents64()( syscalls,更底层)✅ 不要在遍历时改目录
✅ 遍历完再处理
✅ 正确处理 NULL 和 errno
✅ 不要多线程共享 DIR*
✅ 必要时加锁或使用 inotify
如果你能说明:
我可以给你更精确的代码方案。