在 Linux 下使用 readdir 读取目录时,它本身并不提供过滤功能,需要你在拿到每个目录项后自行判断。下面按常见场景说明。
#include <dirent.h>
#include <stdio.h>
int main() {
DIR *dir = opendir(".");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
readdir 会返回:
. 当前目录.. 上级目录. 和 ..if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0)
continue;
使用 entry->d_type(不是所有文件系统都支持)
if (entry->d_type == DT_REG) // 普通文件
printf("file: %s\n", entry->d_name);
if (entry->d_type == DT_DIR) // 目录
printf("dir: %s\n", entry->d_name);
常见类型:
DT_REG 普通文件DT_DIR 目录DT_LNK 符号链接DT_UNKNOWN 未知(需 stat)#include <sys/stat.h>
struct stat st;
char path[256];
snprintf(path, sizeof(path), "./%s", entry->d_name);
if (stat(path, &st) == 0) {
if (S_ISREG(st.st_mode)) // 普通文件
printf("regular file: %s\n", entry->d_name);
if (S_ISDIR(st.st_mode)) // 目录
printf("directory: %s\n", entry->d_name);
}
✅ 适合需要权限、大小、时间等过滤
if (strstr(entry->d_name, ".txt"))
printf("txt file: %s\n", entry->d_name);
或用 fnmatch
#include <fnmatch.h>
if (fnmatch("*.log", entry->d_name, 0) == 0)
printf("log: %s\n", entry->d_name);
. 开头)if (entry->d_name[0] == '.')
continue;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type != DT_REG)
continue;
if (fnmatch("*.c", entry->d_name, 0) != 0)
continue;
printf("%s\n", entry->d_name);
}
scandir(自带过滤和排序)statgetdents64(底层系统调用)如果你有具体过滤条件(比如按时间、大小、权限、递归),可以告诉我,我给你写完整代码。