在 Linux 下,readdir(以及相关的 opendir / readdir_r / getdents)用于读取目录内容,但它有一些使用限制和注意事项,常见如下:
readdir 每次调用只返回一个目录项(struct dirent *),不能一次性拿到整个目录内容。需要循环调用:
while ((entry = readdir(dir)) != NULL) {
...
}
readdir 返回的是目录内的文件名(如 "file.txt"),不是完整路径。
如果需要完整路径,需要自己拼接:
snprintf(path, sizeof(path), "%s/%s", dirpath, entry->d_name);
readdir 不保证返回顺序(通常不是字母序),不同文件系统可能不同。
如果需要排序,必须自己 sort。
. 和 ..目录中一定包含:
. 当前目录.. 上级目录通常需要手动跳过:
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
在遍历目录时:
rename / unlink 正在遍历的项readdir 不是线程安全的(很重要)readdir 使用 目录流内部缓冲区DIR* 不能被多个线程同时使用✅ 正确方式:
DIR*readdir_r(已不推荐)readdir_r 已被废弃readdir_r 为 obsoletereaddir(在单线程上下文)d_type 字段:
DT_UNKNOWN安全写法:
if (entry->d_type == DT_UNKNOWN) {
struct stat st;
stat(path, &st);
}
readdir 会多次系统调用getdents64opendirreaddir 不会自动解析符号链接stat / lstat
readdir简单、稳定,但慢、无序、线程不安全、不返回完整路径、不适合高并发或超大目录。
如果你有具体场景(比如递归遍历、并发扫描、超大目录),我可以给出更合适的方案(如 nftw、getdents64、std::filesystem 等)。