readdir 在 Linux 下“效率低”通常不是函数本身慢,而是使用方式 + 文件系统特性 + 历史实现共同造成的。下面分点说清楚原因,以及什么时候它会慢、怎么优化。
readdir 本身不一定慢readdir 只是从已经打开的目录句柄里取下一个条目opendirgetdents)statreaddir 慢的真实原因readdir 后都 stat(最常见)很多人写的是:
while ((ent = readdir(dir))) {
stat(ent->d_name, &st); // 慢!
}
问题:
readdir 不返回文件类型/元数据stat 系统调用stat✅ 解决:
readdir + d_type(仅部分文件系统支持)statx / getdents64ext3/ext4 目录是线性结构readdir 要顺序扫整个目录表现:
readdir 慢✅ 解决:
xfs / btrfsreaddir 是 glibc 封装,不是 syscall实际流程是:
readdir()
-> getdents64()
✅ 更高效方式:
getdents64(高级用法)d_type如果:
ent->d_type == DT_UNKNOWN
说明:
stat 才能知道是文件还是目录✅ 支持 d_type 的:
❌ 不支持:
表现:
因为:
find 用 fstatat + 批量读取find 避免不必要 statfind 用 FTW / nftw而你手写的可能:
statd_typed_typewhile ((ent = readdir(dir))) {
if (ent->d_type == DT_REG)
// 普通文件
}
scandir(小目录)struct dirent **list;
int n = scandir(path, &list, NULL, alphasort);
getdents64(高性能)
readdir慢,通常不是 readdir 的锅,而是:
- 目录太大
- 每次都 stat
- 文件系统不支持 d_type
- 缓存未命中
如果你愿意,可以告诉我:
我可以直接给你最优遍历方案或代码示例。