温馨提示×

linux readdir会漏文件吗

小樊
40
2026-09-08 15:48:35
栏目: 智能运维

简短结论:正常情况下 readdir 不会“漏”文件,但在某些特殊场景下,可能会“看起来像漏了文件”

下面分情况说清楚。


一、正常情况下:不会漏

单个目录遍历过程中目录内容不变 的情况下:

  • opendir + readdir + closedir
  • 内核会保证返回该目录下所有条目的完整快照(逻辑上)

也就是说:

只要你在遍历期间不修改目录,readdir 不会漏文件。


二、常见“看起来漏文件”的真实原因

1️⃣ 遍历过程中目录被并发修改(最常见)

例如:

  • 另一个进程在 不断创建 / 删除文件
  • 你自己在遍历时删除或重命名文件

结果:

  • 新创建的文件 可能不会被遍历到
  • 已被删除的文件 可能不会再出现
  • 某些文件系统下,遍历顺序会“跳来跳去”

✅ 这不是 bug,而是 POSIX 的明确规定行为。

POSIX 不保证 readdir 能看到遍历开始后才发生的修改


2️⃣ 用了 readdir_r 但 buffer 使用错误(历史坑)

老代码中常见:

struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
    ...
}

这是安全的

但如果你:

  • 手动拷贝 struct dirent
  • 只拷贝了指针而非内容

就可能出现:

  • 文件名错乱
  • 看似“漏文件”

✅ 推荐直接用 readdir,不要用 readdir_r(已废弃)


3️⃣ 符号链接 / 挂载点造成的“错觉”

  • 符号链接指向不存在文件
  • 目录里是挂载点,但没挂载
  • 权限不足导致某些子目录进不去

这会让程序“跳过”,但不是 readdir 漏。


4️⃣ 网络文件系统(NFS / SMB / FUSE)

网络文件系统 上:

  • 文件列表可能来自缓存
  • 服务器和客户端状态不一致
  • 遍历中途网络抖动

可能出现:

  • 文件“时有时无”
  • 看起来像漏了

这是 网络文件系统一致性问题,不是 readdir 本身。


5️⃣ 文件数极大 + 程序逻辑错误

例如:

  • 用了固定大小数组
  • 提前 break
  • 遍历时发生了异常

这其实是你代码漏了,不是系统调用漏。


三、如何避免“看起来漏文件”

✅ 正确做法

DIR *dir = opendir(path);
struct dirent *ent;
while ((ent = readdir(dir)) != NULL) {
    // 处理 ent->d_name
}
closedir(dir);

✅ 如果要求“强一致”

  • stat / scandir 一次性拿到所有文件
  • 或加文件锁
  • 或暂停写入再遍历

✅ 对网络文件系统

  • 降低缓存时间
  • 使用 stat 二次确认
  • 避免边写边读

四、总结一句话

readdir 本身不会漏文件,但在目录被并发修改、网络文件系统、或程序逻辑错误时,会出现“漏文件”的假象。

如果你能说下:

  • 用的文件系统(ext4 / nfs / overlay / tmpfs?)
  • 是否是多线程 / 多进程
  • 具体代码或现象

我可以更精确地判断你遇到的到底是不是“真漏”。

0