温馨提示×

debian readdir如何过滤文件类型

小樊
43
2026-10-19 00:50:23
栏目: 智能运维

在 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;
}

⚠️ 注意:

  • 某些文件系统(如某些 NFS)d_type 可能为 DT_UNKNOWN
  • 此时需要配合 stat() 使用

二、使用 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;
}

四、Shell 层面的“readdir 过滤”

如果你是问命令行而不是 C 程序:

# 只列普通文件
find . -maxdepth 1 -type f

# 只列目录
find . -maxdepth 1 -type d

总结

方法 速度 可靠性 适用场景
d_type 快 中 本地文件系统
stat() 慢 高 精确判断
find 最简单 高 Shell 使用

如果你是 C / C++ / Python / Shell 哪种场景,我可以给你更具体的示例。

0 踩