在 Ubuntu(以及大多数 Linux 系统)里,之所以用 opendir() 来遍历目录,是因为这是 POSIX 标准规定的目录操作接口,而不是 Ubuntu 自己“发明”的。下面从几个层面解释一下。
opendir() 是什么?opendir() 是 C 标准库(glibc) 和 POSIX 标准 定义的函数,用来打开一个目录流(directory stream)。
#include <dirent.h>
DIR *opendir(const char *name);
它的作用是:
DIR * 指针(目录流)readdir() 逐个读取目录项opendir()?POSIX(Portable Operating System Interface)规定了一套跨 Unix-like 系统的 API,其中就包括:
| 操作 | 函数 |
|---|---|
| 打开目录 | opendir() |
| 读取目录 | readdir() |
| 关闭目录 | closedir() |
| 重新定位 | rewinddir() |
Ubuntu 作为 Linux + glibc 的实现,自然遵循这个标准,以保证:
在 Linux 中:
open() + read() 读为什么?
所以内核提供了 抽象接口:
opendir()
↓
调用系统调用 getdents()
↓
内核解析目录结构
↓
返回标准化结构给应用
readdir() 返回的是:
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256];
};
好处是:
opendir()?int fd = open("/tmp", O_RDONLY);
read(fd, buf, size); // ❌ 错误
Linux 提供了系统调用:
getdents() / getdents64()
但:
opendir() 实际上就是对 getdents() 的封装。
如果你用的是 C++17 及以上:
#include <filesystem>
for (auto& p : std::filesystem::directory_iterator(".")) {
std::cout << p.path() << std::endl;
}
✅ 这是现代做法
✅ 在 Ubuntu 上完全可用
但底层仍然是:
opendir() / getdents()
Ubuntu 用
opendir(),是因为它是 POSIX 标准规定的、安全、可移植、不依赖具体文件系统的目录遍历接口。
如果你愿意,我可以:
opendir → getdents → 内核 的调用流程图FindFirstFileopendir/readdir 示例