温馨提示×

linux readdir如何过滤

小樊
50
2026-10-02 17:02:04
栏目: 智能运维

在 Linux 下使用 readdir()(或 readdir_r())遍历目录时,readdir 本身并不支持过滤条件,只能在拿到每个目录项(struct dirent)后,在用户态自己判断、过滤。

下面按常见场景说明如何“过滤”。


一、readdir 基本用法

#include <dirent.h>
#include <stdio.h>

DIR *dir = opendir("/path");
struct dirent *entry;

while ((entry = readdir(dir)) != NULL) {
    printf("%s\n", entry->d_name);
}
closedir(dir);

⚠️ 注意:readdir 会返回:

  • .
  • ..
  • 所有文件/目录/符号链接等

二、常见过滤方式

1️⃣ 按文件名过滤

while ((entry = readdir(dir)) != NULL) {
    // 跳过 . 和 ..
    if (strcmp(entry->d_name, ".") == 0 ||
        strcmp(entry->d_name, "..") == 0)
        continue;

    // 只处理 .txt 文件
    if (strstr(entry->d_name, ".txt"))
        printf("%s\n", entry->d_name);
}

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

d_type 可判断类型(不是所有文件系统都支持)

while ((entry = readdir(dir)) != NULL) {
    if (entry->d_type == DT_REG)      // 普通文件
        printf("FILE: %s\n", entry->d_name);
    else if (entry->d_type == DT_DIR) // 目录
        printf("DIR : %s\n", entry->d_name);
}

常见类型:

  • DT_REG:普通文件
  • DT_DIR:目录
  • DT_LNK:符号链接
  • DT_UNKNOWN:未知(需 stat)

3️⃣ 精确判断文件类型(最可靠)

当 d_type == DT_UNKNOWN 时:

#include <sys/stat.h>

struct stat st;
char path[256];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);

if (stat(path, &st) == 0) {
    if (S_ISREG(st.st_mode))  // 普通文件
        printf("REG: %s\n", entry->d_name);
    if (S_ISDIR(st.st_mode))  // 目录
        printf("DIR: %s\n", entry->d_name);
}

4️⃣ 使用 glob / scandir(更“过滤友好”)

✅ scandir(自带过滤函数)

struct dirent **namelist;
int n = scandir(".", &namelist, NULL, alphasort);

for (int i = 0; i < n; i++) {
    printf("%s\n", namelist[i]->d_name);
    free(namelist[i]);
}
free(namelist);

自定义过滤:

int filter(const struct dirent *e) {
    return strncmp(e->d_name, "log", 3) == 0;
}

scandir(".", &namelist, filter, alphasort);

5️⃣ 正则表达式过滤(高级)

#include <regex.h>

regex_t reg;
regcomp(&reg, ".*\\.conf$", 0);

if (regexec(&reg, entry->d_name, 0, NULL, 0) == 0)
    printf("%s\n", entry->d_name);

regfree(&reg);

三、总结

需求 推荐方式
简单文件名 strstr / strcmp
文件类型 d_type + stat
内置过滤 scandir
复杂规则 regex

✅ readdir 本身不过滤,只能“读出来再判断”

如果你有具体场景(比如:只遍历文件、递归目录、隐藏文件、权限过滤),可以告诉我,我给你写完整示例。

0 踩