在 Linux 下使用 readdir(通常指 readdir() 或 readdir_r(),来自 <dirent.h>)时,**“怎样判断”**一般指的是几类情况:判断是否读到了目录项、判断文件类型、判断是否读完、判断是否出错。下面系统说明。
#include <dirent.h>
#include <stdio.h>
DIR *dir = opendir("/path");
if (!dir) {
perror("opendir");
return -1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
if (entry != NULL) {
// 读到一个目录项
}
while ((entry = readdir(dir)) != NULL) {
// 还有内容
}
// 跳出循环 = 读完了
readdir返回NULL有两种可能:
- 正常读完
- 出错(需配合
errno)
errno = 0;
entry = readdir(dir);
if (entry == NULL) {
if (errno != 0) {
perror("readdir");
} else {
// 正常结束
}
}
struct dirent 中有:
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256];
};
d_type 判断(推荐,高效)switch (entry->d_type) {
case DT_REG: printf("普通文件\n"); break;
case DT_DIR: printf("目录\n"); break;
case DT_LNK: printf("符号链接\n"); break;
case DT_CHR: printf("字符设备\n"); break;
case DT_BLK: printf("块设备\n"); break;
case DT_FIFO: printf("管道\n"); break;
case DT_SOCK: printf("socket\n"); break;
case DT_UNKNOWN: printf("未知类型\n"); break;
}
⚠️ 注意:
d_type 可能是 DT_UNKNOWN若 d_type == DT_UNKNOWN,用 stat:
#include <sys/stat.h>
struct stat st;
char path[512];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
if (stat(path, &st) == 0) {
if (S_ISREG(st.st_mode)) printf("普通文件\n");
if (S_ISDIR(st.st_mode)) printf("目录\n");
if (S_ISLNK(st.st_mode)) printf("链接\n");
}
. 和 ..if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
if (entry->d_type == DT_REG)
if (entry->d_type == DT_DIR)
struct dirent entry;
struct dirent *result;
readdir_r(dir, &entry, &result);
if (result == NULL) {
// 结束或出错
}
⚠️ 现代 glibc 推荐直接用
readdir
readdir 判断逻辑:
NULL → 结束或出错(看 errno)d_type → 快速判断文件类型stat → 精确判断. / .. 是常规操作如果你有具体场景(比如递归遍历、过滤文件、C++/Rust 实现),可以继续问。