温馨提示×

linux readdir怎样过滤

小樊
41
2026-09-17 19:55:05
栏目: 智能运维

在 Linux 下使用 readdir 读取目录时,它本身并不提供过滤功能,需要你在拿到每个目录项后自行判断。下面按常见场景说明。


一、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 会返回:

  • . 当前目录
  • .. 上级目录
  • 其他普通文件 / 目录 / 设备等

二、常见过滤方式

1️⃣ 过滤 ...

if (strcmp(entry->d_name, ".") == 0 ||
    strcmp(entry->d_name, "..") == 0)
    continue;

2️⃣ 按文件类型过滤(推荐)

使用 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)

3️⃣ 使用 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);
}

✅ 适合需要权限、大小、时间等过滤


4️⃣ 按文件名后缀过滤

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);

5️⃣ 隐藏文件过滤(以 . 开头)

if (entry->d_name[0] == '.')
    continue;

三、综合示例(只显示普通 .c 文件)

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(自带过滤和排序)
  • 需要递归 → 自己写递归 + stat
  • 高并发 / 性能 → getdents64(底层系统调用)

如果你有具体过滤条件(比如按时间、大小、权限、递归),可以告诉我,我给你写完整代码。

0