在 Debian(Linux)下,使用 readdir() 读取目录时,readdir 本身不能直接按文件类型过滤,它只是把目录项(struct dirent)返回给你。过滤文件类型通常有两种做法:
readdir + d_type(推荐,简单高效)struct dirent 中有个字段:
unsigned char d_type;
常见取值:
DT_REG 普通文件DT_DIR 目录DT_LNK 符号链接DT_CHR 字符设备DT_BLK 块设备DT_FIFO 管道DT_SOCK 套接字#include <dirent.h>
#include <stdio.h>
int main() {
DIR *dir = opendir(".");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG) {
printf("file: %s\n", entry->d_name);
}
}
closedir(dir);
return 0;
}
⚠️ 注意:
d_type 可能为 DT_UNKNOWNstat() 使用readdir + stat(最可靠)当你需要精确判断文件类型(尤其是 d_type == DT_UNKNOWN)时:
#include <dirent.h>
#include <sys/stat.h>
#include <stdio.h>
int main() {
DIR *dir = opendir(".");
struct dirent *entry;
struct stat st;
while ((entry = readdir(dir)) != NULL) {
if (stat(entry->d_name, &st) == -1)
continue;
if (S_ISREG(st.st_mode)) {
printf("regular file: %s\n", entry->d_name);
}
}
closedir(dir);
return 0;
}
宏说明:
S_ISREG(m) 普通文件S_ISDIR(m) 目录S_ISLNK(m) 符号链接S_ISCHR(m) 字符设备S_ISBLK(m) 块设备S_ISFIFO(m) 管道S_ISSOCK(m) 套接字if (entry->d_type == DT_DIR) {
// 排除 . 和 ..
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
}
如果你是问命令行而不是 C 程序:
# 只列普通文件
find . -maxdepth 1 -type f
# 只列目录
find . -maxdepth 1 -type d
| 方法 | 速度 | 可靠性 | 适用场景 |
|---|---|---|---|
d_type |
快 | 中 | 本地文件系统 |
stat() |
慢 | 高 | 精确判断 |
find |
最简单 | 高 | Shell 使用 |
如果你是 C / C++ / Python / Shell 哪种场景,我可以给你更具体的示例。