在 Debian(以及大多数 Linux 发行版)中,readdir 本身几乎不会“漏文件”,如果出现“目录里明明有文件,但 readdir 没读到”的情况,通常不是 glibc/内核 bug,而是使用方式或环境差异导致的。下面按最常见 → 较少见顺序说明原因和排查方法。
readdir 不是快照语义:
opendir() 之后、读取完成前:
✅ 这是 POSIX 的明确规定,不是 bug
解决方法
open() 目录fcntl(fd, F_SETLK, ...) 上锁readdir 必须循环调用:
while ((ent = readdir(dir)) != NULL) {
...
}
常见错误:
break✅ 结果:看起来“少文件”
. 和 .. 被忽略(误以为漏文件)readdir 一定会返回:
.
..
如果你在统计“普通文件”,却忘了过滤它们,或反过来以为它们不该出现,就会误判。
✅ 正确做法:
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
continue;
Debian 默认 UTF-8:
✅ 排查方法:
ls | cat -v
或:
printf("name: %s\n", ent->d_name);
出现在:
现象:
ls 能看到readdir 却看不到✅ 排查:
mount | grep 目录
stat 目录
✅ 解决:
echo 3 > /proc/sys/vm/drop_cachesreaddir 内部使用 getdents✅ 检查:
SA_RESTARTent->d_type
⚠ 不是所有文件系统都支持
错误示例:
if (ent->d_type == DT_REG) // 可能在 NFS 上全为 DT_UNKNOWN
✅ 正确做法:
struct stat st;
lstat(path, &st);
现象:
✅ 排查:
dmesg | grep -i error
✅ 修复:
umount /dev/sdX
fsck -f /dev/sdX
Debian stable 上几乎不可能。
如果你怀疑:
请逐条确认:
. / ..d_type你可以直接贴:
我可以精确指出是哪一条导致“漏文件”,甚至给你一版“绝对不会漏”的目录遍历代码。