在 Linux 下使用 readdir()(或 readdir_r())遍历目录时,“漏读”通常不是 readdir 本身的 bug,而是使用方式或并发场景导致的问题。下面系统说明常见原因和解决办法。
DIR *dir = opendir(path);
if (!dir) { perror("opendir"); return; }
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
// 处理 entry
}
closedir(dir);
⚠️ 常见错误:
readdirwhile 条件里做了额外判断导致提前 breakreaddir_r 但没检查返回值在遍历目录时:
readdir 基于目录的 offset(目录项偏移),不是快照。
opendir// 先读出所有文件名
std::vector<std::string> names;
DIR *dir = opendir(path);
struct dirent *e;
while ((e = readdir(dir)))
names.push_back(e->d_name);
closedir(dir);
✅ 简单、安全
❌ 不适合超大目录
flock)flock(dirfd(dir), LOCK_SH);
// readdir
flock(dirfd(dir), LOCK_UN);
⚠️ 只防“自己程序”,不防别的进程
inotify 监听适合“实时同步”类程序
readdir 不是线程安全readdir_r 才是但很多人用错:
struct dirent entry;
struct dirent *result;
readdir_r(dir, &entry, &result);
✅ 正确做法:
struct dirent *entry = malloc(sizeof(struct dirent));
struct dirent *result;
readdir_r(dir, entry, &result);
. 和 .. 被忽略✅ 建议:
if (entry->d_name[0] == '.') continue; // 按需
某些文件系统(网络 FS、FUSE):
✅ 解决:
getdents64✅ 必做:
NULLreaddir_r✅ 推荐:
如果你愿意,可以告诉我:
我可以给你针对性代码示例。