在 CentOS(以及其它 Linux 系统)上,readdir 和 scandir 都是用来读取目录内容的函数,但它们在使用方式、性能、返回信息上有明显区别。下面从系统调用 / glibc 层面说明。
readdir()<dirent.h>opendir()
readdir()
closedir()
DIR *dir = opendir("/path");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
struct dirent 只包含:
d_namestat()stat 每个文件scandir()<dirent.h>struct dirent **namelist;
int n = scandir("/path", &namelist, NULL, alphasort);
for (int i = 0; i < n; i++) {
printf("%s\n", namelist[i]->d_name);
free(namelist[i]);
}
free(namelist);
struct dirent ** 数组alphasort)dirent,不含 stat 信息| 对比项 | readdir | scandir |
|---|---|---|
| 读取方式 | 逐个读取 | 一次性读取 |
| 内存占用 | 低 | 高(存整个目录) |
| 排序 | 无 | 支持 |
| 过滤 | 手动 | 支持 filter |
| 大目录 | 友好 | 不友好 |
| 使用复杂度 | 稍高 | 简单 |
在 CentOS 上常见性能瓶颈:
readdir()
stat() // 每个文件一次系统调用
解决方式(更现代):
readdir + fstatat(减少路径解析)fts_open / nftwscandiratopendir + readdirscandirscandir 读几万文件的目录如果你需要:
ls / find 的实现对比可以继续问。