在 Debian(以及其它 Linux 发行版)里,readdir 并不是“一个程序”,而是 C 库(glibc)提供的目录读取函数,底层依赖 Linux 内核的 getdents / getdents64 系统调用。下面从「用户态 → glibc → 内核 → 文件系统」逐层说明它是如何工作的。
readdir 是什么readdir 定义在:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
作用:从已打开的目录流中读取下一个目录项(文件/子目录)。
常见相关函数:
opendir() → 打开目录,返回 DIR*readdir() → 逐个读取目录项closedir() → 关闭目录rewinddir() / seekdir() → 目录流定位opendir()DIR *dir = opendir("/tmp");
内部大致做了:
open("/tmp", O_RDONLY | O_DIRECTORY)DIR 结构体readdir()struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
readdir 的工作方式:
getdents64() 一次读一批目录项struct direntgetdents64readdir 最终调用:
int getdents64(int fd, struct linux_dirent64 *buf, int count);
这是在 VFS 层 实现的:
用户程序
↓
glibc readdir
↓
sys_getdents64
↓
vfs_readdir
↓
具体文件系统 (ext4 / xfs / overlayfs ...)
内核一次可能返回 多个目录项,减少系统调用次数。
在 ext4 中:
目录项 (directory entry) 组成读取过程:
linux_dirent64struct dirent 内容说明struct dirent {
ino_t d_ino; // inode 号
off_t d_off; // 偏移(用于 seekdir)
unsigned short d_reclen; // 记录长度
unsigned char d_type; // 文件类型
char d_name[]; // 文件名
};
⚠️ 注意:
readdir 不保证顺序. 和 .. 也可能被返回readdir_r,但已废弃)在 Debian / Linux 中:
readdir 过程中:
O_DIRECTORY + fs 特性 或快照)#include <dirent.h>
#include <stdio.h>
int main() {
DIR *d = opendir(".");
struct dirent *e;
while ((e = readdir(d)))
printf("%s\n", e->d_name);
closedir(d);
}
strace ./a.outopenat, getdents64ls -Ureaddir 顺序cat /proc/sys/fs/dentry-state如果你愿意,我可以进一步讲:
readdir vs getdents 性能差异readdir 在 NFS 上行为不同getdents64 自己实现 readdir你想深入哪一块?