在 Linux 下使用 readdir 主要是用来遍历目录中的文件和子目录。readdir 是 POSIX 标准 C 库函数,定义在 <dirent.h> 中,常用于 Linux/Unix 目录操作。
下面从基本概念 → 示例代码 → 常见用法与注意点系统说明。
#include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dirp);
int closedir(DIR *dirp);
struct dirent {
ino_t d_ino; // inode 号
off_t d_off;
unsigned short d_reclen;
unsigned char d_type; // 文件类型(部分系统支持)
char d_name[256]; // 文件名
};
#include <stdio.h>
#include <dirent.h>
int main() {
DIR *dir = opendir(".");
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
./readdir_example
. 和 ..readdir 会返回 . 和 ..,通常需要过滤:
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
printf("%s\n", entry->d_name);
}
d_type(不一定全支持)if (entry->d_type == DT_REG) {
printf("普通文件: %s\n", entry->d_name);
} else if (entry->d_type == DT_DIR) {
printf("目录: %s\n", entry->d_name);
}
⚠️ 注意:某些文件系统(如 NFS)可能 d_type == DT_UNKNOWN
lstat / stat#include <sys/stat.h>
#include <string.h>
struct stat st;
char path[512];
snprintf(path, sizeof(path), "./%s", entry->d_name);
lstat(path, &st);
if (S_ISREG(st.st_mode)) {
printf("文件: %s\n", entry->d_name);
} else if (S_ISDIR(st.st_mode)) {
printf("目录: %s\n", entry->d_name);
}
void list_dir(const char *path) {
DIR *dir = opendir(path);
if (!dir) return;
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
printf("%s/%s\n", path, entry->d_name);
}
closedir(dir);
}
readdir 使用静态缓冲区readdir_r(dir, entry, &result); // 已废弃
✅ 现代推荐:
readdirDIR*需要自己拼接完整路径:
sprintf(path, "%s/%s", dirname, entry->d_name);
if (opendir(path) == NULL) {
perror("opendir");
}
| 函数 | 特点 |
|---|---|
| readdir | 流式读取,内存占用小 |
| scandir | 一次性返回数组,方便排序 |
int scandir(const char *dir, struct dirent ***namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **));
✅ readdir 使用流程:
opendir → readdir → 处理 d_name → closedir
✅ 适合:
ls 类似功能如果你需要:
可以告诉我你的具体使用场景,我可以给你更贴近实战的代码。