在 Debian(以及其它 Linux 发行版)里,readdir 和 ls 经常被一起提到,但它们根本不在同一个层次上。简单说:
ls是一个用户命令(程序)
readdir是一个系统/库函数(编程接口)
下面分层说明。
| 项目 | ls | readdir |
|---|---|---|
| 类型 | 命令行程序(binary) | C 库函数(glibc) |
| 使用对象 | 普通用户 | 程序员 |
| 作用 | 显示目录内容 | 读取目录项 |
| 所在位置 | /bin/ls |
<dirent.h> |
| 是否系统调用 | 否(内部会调用系统调用) | 否(内部调用 getdents) |
ls 是 用户空间的可执行程序:
which ls
# /bin/ls
ls /etc
它做的事情包括:
stat 获取文件详细信息底层流程大概是这样:
ls
└─ opendir()
└─ readdir() ← 这里用到 readdir
└─ stat()
└─ 输出到终端
readdir 是 C 语言函数,定义在:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
作用是:从已打开的目录中读取一个目录项(文件名)
示例(C 程序):
DIR *d = opendir(".");
struct dirent *e;
while ((e = readdir(d)) != NULL) {
printf("%s\n", e->d_name);
}
closedir(d);
注意:
readdir 只给文件名. 文件过滤真实读取目录内容的是系统调用:
ls
└─ readdir() (glibc)
└─ getdents64() (syscall)
可以用 strace 看:
strace ls /tmp
你会看到:
openat()getdents64()statx()readdir 是命令不是,不能直接在 shell 里用。
ls 直接读磁盘不是,ls 通过标准库和系统调用完成。
readdir 能看到文件详情不能,只返回:
ls是你用的命令,readdir是ls在代码里用来读目录的函数之一。
如果你愿意,我也可以:
strace 对比 ls 和 readdirreaddir vs scandirls 比 readdir 慢