在 Ubuntu(Linux)下,readdir 通常是指 POSIX 目录读取函数 readdir(),用于遍历目录中的文件和子目录。下面从基本用法、示例代码、常见错误、替代方案几个方面说明如何“正确使用”。
readdir 是 <dirent.h> 提供的函数,用于逐个读取目录项:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);
DIR*:目录流(由 opendir() 返回)struct dirent 的指针NULL⚠️ readdir 不是线程安全的(线程安全版本是 readdir_r,但已不推荐)
opendir() → 打开目录
readdir() → 循环读取
closedir() → 关闭目录
#include <stdio.h>
#include <dirent.h>
int main(int argc, char *argv[]) {
const char *path = ".";
DIR *dir = opendir(path);
if (dir == NULL) {
perror("opendir");
return 1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
编译:
gcc readdir_example.c -o readdir_example
struct dirent {
ino_t d_ino; // inode 号
off_t d_off;
unsigned short d_reclen;
unsigned char d_type; // 文件类型
char d_name[]; // 文件名
};
| 值 | 含义 |
|---|---|
| DT_REG | 普通文件 |
| DT_DIR | 目录 |
| DT_LNK | 符号链接 |
| DT_UNKNOWN | 未知(需 stat) |
示例:只列目录
if (entry->d_type == DT_DIR) {
printf("[DIR] %s\n", entry->d_name);
}
DIR *dir = opendir(path); // 可能 NULL
✅ 必须检查
errno = 0;
entry = readdir(dir);
if (entry == NULL && errno != 0) {
// 错误
}
✅ 正确(但很多人漏)
readdir 不保证顺序qsort. 和 ..if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
void list_dir(const char *path) {
DIR *dir = opendir(path);
if (!dir) return;
struct dirent *entry;
while ((entry = readdir(dir))) {
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
continue;
char full[1024];
snprintf(full, sizeof(full), "%s/%s", path, entry->d_name);
if (entry->d_type == DT_DIR) {
printf("DIR: %s\n", full);
list_dir(full);
} else {
printf("FILE: %s\n", full);
}
}
closedir(dir);
}
#include <filesystem>
for (auto &p : std::filesystem::directory_iterator(".")) {
std::cout << p.path() << "\n";
}
ls -1
find .
✅ 正确使用 readdir 的要点:
opendir → readdir → closedir. 和 ..stat如果你是想问:
可以告诉我具体场景,我可以给更针对性的示例。