温馨提示×

Debian readdir如何遍历

小樊
45
2026-08-12 07:08:09
栏目: 智能运维

在 Debian(以及所有 Linux)下,遍历目录通常是通过 opendir / readdir / closedir 这组 POSIX API 完成的。下面从原理、示例、常见坑几个方面说明。


一、readdir 基本原理

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

核心函数:

函数 作用
opendir() 打开目录
readdir() 读取目录项
closedir() 关闭目录

⚠️ readdir() 返回的是 struct dirent*,不是文件名数组。


二、最简单的 readdir 遍历示例

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

int main(int argc, char *argv[])
{
    const char *path = ".";
    DIR *dir = opendir(path);
    if (!dir) {
        perror("opendir");
        return 1;
    }

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

    closedir(dir);
    return 0;
}

编译 & 运行

gcc readdir.c -o readdir
./readdir

三、过滤 . 和 ..

readdir() 会返回 . 和 ..,通常需要跳过:

#include <string.h>

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

    printf("%s\n", entry->d_name);
}

四、区分文件 / 目录(推荐做法)

d_type 不是 100% 可靠(某些文件系统不支持),推荐用 lstat:

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

while ((entry = readdir(dir)) != NULL) {
    struct stat st;
    char fullpath[512];

    snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);

    if (lstat(fullpath, &st) == -1)
        continue;

    if (S_ISDIR(st.st_mode))
        printf("[DIR]  %s\n", entry->d_name);
    else
        printf("[FILE] %s\n", entry->d_name);
}

五、递归遍历目录(类似 find)

void walk(const char *path)
{
    DIR *dir = opendir(path);
    if (!dir) return;

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strcmp(entry->d_name, ".") == 0 ||
            strcmp(entry->d_name, "..") == 0)
            continue;

        char fullpath[512];
        snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);

        printf("%s\n", fullpath);

        struct stat st;
        if (lstat(fullpath, &st) == 0 && S_ISDIR(st.st_mode))
            walk(fullpath);
    }

    closedir(dir);
}

六、readdir 与 readdir_r(重要)

✅ 现在推荐用 readdir()(线程不安全但简单)
❌ readdir_r() 已被 POSIX 废弃

如果你需要线程安全,可以:

  • 加锁
  • 或自己复制 d_name

七、常见问题

1. 为什么 readdir 返回 . 和 …?

这是 POSIX 标准行为,必须手动过滤。

2. 为什么 d_type 有时是 DT_UNKNOWN?

某些文件系统(如 XFS、NFS)不提供类型信息,要用 stat()。

3. Debian 下需要安装什么?

不需要额外库,标准 C 库自带。


八、总结一句话

Debian 下遍历目录 = opendir → readdir → 处理 d_name → closedir

如果你需要:

  • C++ 版本
  • 只遍历普通文件
  • 按时间 / 大小排序
  • 模拟 ls / find

可以直接告诉我,我可以给你完整示例。

0 踩