在 Ubuntu(本质是 Linux 的 glibc + 内核 VFS)里,readdir 本身不一定“慢”,但在很多场景下会显得效率很低,常见原因可以归为下面几类。
readdir vs readdir_r / getdents 的抽象层级readdir(3) 是 glibc 的库函数getdents64(2) 系统调用glibc 的 readdir:
readdir 一个一个处理」➡ 如果目录有 几十万 / 上百万文件,这种“一次一个”的模式:
Linux 的目录本质是:
readdir 仍按 inode 顺序或哈希顺序返回问题:
✅ 这是“readdir 慢”的最常见场景
不同 FS 对目录遍历的支持差异巨大:
| 文件系统 | readdir 性能 |
|---|---|
| ext4 | 一般(大目录明显慢) |
| xfs | 较好 |
| btrfs | 大目录较差 |
| NFS | 非常慢 |
| overlayfs | 可能极慢 |
| tmpfs | 快 |
尤其是:
都会让 readdir 明显变慢。
Linux 有:
dentry cacheinode cache如果:
readdir 会触发:
➡ 表现为“卡一下”
低效用法(常见):
while ((d = readdir(dir))) {
stat(d->d_name, &st); // ❌ 每个文件一次 stat
}
问题:
stat 是额外系统调用✅ 更好方式:
readdir + d_typegetdents64 自己解析scandir(但内存占用高)readdir 不是为“搜索”设计的readdir 的语义是:
“把目录里的东西一个一个给我”
它 不是:
如果你用它做:
那就是用错工具了。
✅ 正确做法:
getdents64 批量读stat 每文件调用d_type 过滤inotify 代替轮询Ubuntu 下
readdir“慢”,大多不是函数本身慢,而是:目录太大、FS 不适合、使用方式低效。
如果你愿意,可以告诉我:
我可以直接给你最优实现方案。