温馨提示×

linux readdir为何漏文件

小樊
34
2026-09-17 20:05:07
栏目: 智能运维

在 Linux 下使用 readdir()(或 opendir()/readdir() 系列)时“漏文件”,通常不是 readdir() 本身有 bug,而是使用方式或场景导致看起来“少文件”。下面按常见原因逐一说明。


1. 最常见:在遍历目录时修改了目录

现象

  • 遍历过程中创建/删除/重命名文件
  • 某些文件“没被读到”或“被读了两次”

原因

readdir() 返回的是目录项在底层文件系统中的顺序(通常是 inode 或 hash 顺序),而不是快照。
如果在遍历时:

  • 新建文件:可能插到当前位置之后 → 可能漏读
  • 删除文件:可能已跳过或未返回
  • 重命名:可能重复或丢失

正确做法

  • readdir() 收集所有文件名到数组
  • 关闭目录后再做增删改
while ((ent = readdir(dir))) {
    names[n++] = strdup(ent->d_name);
}
closedir(dir);

2. 只处理了一次 readdir 的返回值(逻辑错误)

错误示例

ent = readdir(dir);
printf("%s\n", ent->d_name);  // 只读了一次

正确写法

while ((ent = readdir(dir)) != NULL) {
    ...
}

3. 忽略了 ... 但误以为漏了

readdir() 一定会返回

  • .
  • ..

如果你过滤了它们,但统计总数时没算,会“以为漏了”。

if (strcmp(ent->d_name, ".") == 0 ||
    strcmp(ent->d_name, "..") == 0)
    continue;

4. 目录太大 / 并发高(极端情况)

  • 某些文件系统(如 ext4, xfs)在高并发写
  • readdir() 不保证一致性(非 POSIX 强一致)

解决:

  • 使用 fsync + 暂停写入
  • 或改用 stat() 逐个确认

5. 挂载点 / 符号链接 / 绑定挂载

常见坑

  • 目录是 挂载点
  • 实际文件在另一文件系统
  • readdir() 只看到挂载点本身

检查:

mount | grep 目录
ls -l 目录

6. 权限问题(不是漏,是看不到)

  • r 权限:目录打不开
  • x 权限:能看到目录但读不到内容
ls -ld 目录

7. 使用了缓存(用户态/内核态)

  • NFS
  • FUSE
  • Docker 挂载

可能看到旧目录项。


8. 你用的是 scandir() / glob() 但模式写错

例如:

glob("*.txt", ...);  // 隐藏文件漏了

9. 文件数量超过预期但被截断

某些旧实现或错误:

  • d_name 缓冲区太小
  • 未使用 readdir_r() 或线程安全版本

总结一句话

readdir() 不会“随机漏文件”,漏文件几乎总是:遍历中改目录、逻辑错误、或文件系统特性。

如果你愿意,可以把:

  • 使用的语言(C / C++ / Python)
  • 代码片段
  • 文件系统类型(ext4 / NFS / overlay)

发出来,我可以直接帮你定位是哪一种。

0