温馨提示×

centos readdir为啥丢文件

小樊
42
2026-10-09 01:26:02
栏目: 智能运维

在 CentOS(或者说 Linux 通用的 readdir / getdents 机制)里,“readdir 丢文件”通常不是真的丢了,而是使用方式或环境导致看起来少了。下面按常见原因给你排一下:


1. 最常见:循环里用了 readdir,但中途修改了目录

现象

遍历目录时,如果在循环中:

  • 删除文件
  • 新建文件
  • rename 文件

就可能导致某些文件不被 readdir 返回。

原因

readdir 底层是 getdents,它依赖内核返回的目录项游标。目录结构在遍历过程中变化,会导致:

  • 新文件可能看不到
  • 某些 entry 被跳过

✅ 解决

  • 先 readdir 把所有文件名存到数组
  • 再统一处理
while ((de = readdir(dir))) {
    names.push_back(de->d_name);
}
closedir(dir);
// 再处理 names

2. 只看了 d_name,忽略了 . 和 ..

有些新手会这样写:

if (de->d_name[0] == '.') continue;

这会直接跳过隐藏文件,看起来像“丢文件”。


3. 目录项太多,缓冲区不够(C / 系统调用层)

如果你是:

  • 直接用 getdents
  • 或自己管理 buffer

buffer 太小会导致:

  • 一次读不全
  • 处理不当就“漏”

✅ 建议

  • 用标准 opendir/readdir
  • 不要手工 getdents 除非你很清楚

4. NFS / 网络文件系统(非常常见!)

CentOS 上如果目录在:

  • NFS
  • GlusterFS
  • CephFS

readdir 丢文件是高概率事件

原因

  • NFS 的 readdir 是“有状态游标”
  • 网络抖动 / 重新 mount
  • 服务端并发写入

都会导致:

  • 某些文件不被返回
  • 甚至重复返回

✅ 解决

  • 避免遍历中写
  • 或先 ls > filelist
  • 或改用 find

5. 文件系统是 overlay / tmpfs / bind mount

如果你是:

  • Docker 容器
  • Kubernetes
  • overlayfs

readdir 可能:

  • 看不到下层文件
  • 或 upper / lower 不一致

6. 目录超过一定大小(ext4 大目录)

ext4 大目录(几万+文件):

  • hash tree 索引
  • 并发写入时 readdir 可能不稳定

7. 你用的不是 readdir,而是 scandir 但 filter 写错

scandir(path, &namelist, filter, alphasort);

filter 返回非 0 才保留,写反了就“丢”。


8. SELinux / 权限问题(看起来像丢)

  • 进程无权限
  • SELinux 禁止访问

某些文件直接 不返回,而不是 EACCES。


快速自查清单 ✅

  1. 是不是在遍历中改目录?
  2. 是不是 NFS / 容器目录?
  3. 是不是跳了 . 开头?
  4. 是不是自己用 getdents?
  5. 用 ls / find 对比一下数量

如果你愿意,可以把:

  • 你的 代码片段
  • 目录类型(本地 / NFS / 容器)
  • 文件数量级

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

0 踩