在 CentOS(Linux) 下用 C 语言遍历目录,通常使用的是 opendir / readdir / closedir 这套 POSIX 接口。下面给你一个标准用法示例,以及常见注意点。
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
DIR *dir;
struct dirent *entry;
if (argc < 2) {
fprintf(stderr, "usage: %s <dir>\n", argv[0]);
return 1;
}
dir = opendir(argv[1]);
if (dir == NULL) {
perror("opendir");
return 1;
}
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
编译:
gcc readdir_test.c -o readdir_test
运行:
./readdir_test /etc
readdir 返回的结构体struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_rechlen;
unsigned char d_type; // DT_REG, DT_DIR ...
char d_name[256];
};
常用字段:
d_name:文件名d_type:文件类型(可选,不一定所有文件系统都支持)while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
printf("[DIR] %s\n", entry->d_name);
} else {
printf("[FILE] %s\n", entry->d_name);
}
}
⚠️ 注意:
DT_UNKNOWN 时,需要用 stat() 判断. 和 .. 会被遍历到,一般需要过滤find)#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
void list_dir(const char *path)
{
DIR *dir = opendir(path);
if (!dir) return;
struct dirent *entry;
char fullpath[1024];
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
struct stat st;
stat(fullpath, &st);
if (S_ISDIR(st.st_mode)) {
printf("DIR: %s\n", fullpath);
list_dir(fullpath);
} else {
printf("FILE: %s\n", fullpath);
}
}
closedir(dir);
}
头文件
#include <dirent.h>
#include <sys/types.h>
线程安全
readdir 不是线程安全readdir_r(旧)或 readdir + 加锁(新 glibc)大目录性能
readdir 是顺序读,性能很好stat()✅ 遍历目录标准流程:
opendir → readdir → 处理 → closedir
如果你需要:
getdents 系统调用可以直接说你的使用场景。