温馨提示×

linux readdir如何递归

小樊
47
2026-09-11 14:08:54
栏目: 智能运维

在 Linux 下使用 readdir 进行递归遍历目录,核心思路是:

  1. 用 opendir 打开目录
  2. 用 readdir 读取目录项
  3. 对每个目录项:
    • 跳过 . 和 ..
    • 用 stat / lstat 判断是否是目录
    • 如果是目录,递归调用自己
  4. 用 closedir 关闭目录

基础示例(递归列出所有文件)

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

void list_dir(const char *path) {
    DIR *dir = opendir(path);
    if (!dir) {
        perror("opendir");
        return;
    }

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

        // 拼接完整路径
        char fullpath[1024];
        snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);

        struct stat st;
        if (stat(fullpath, &st) == -1) {
            perror("stat");
            continue;
        }

        if (S_ISDIR(st.st_mode)) {
            printf("DIR:  %s\n", fullpath);
            list_dir(fullpath);   // 递归
        } else {
            printf("FILE: %s\n", fullpath);
        }
    }

    closedir(dir);
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("usage: %s <dir>\n", argv[0]);
        return 1;
    }
    list_dir(argv[1]);
    return 0;
}

关键点说明

1. readdir 只读取目录项

  • 本身 不知道是不是目录
  • 需要 stat() 或 lstat()

2. 符号链接处理

  • 用 lstat:不会跟随符号链接
  • 用 stat:会跟随符号链接(可能死循环)

避免递归符号链接目录:

lstat(fullpath, &st);
if (S_ISLNK(st.st_mode)) {
    // 符号链接,不递归
}

更安全的递归版本(避免符号链接循环)

if (lstat(fullpath, &st) == 0 && S_ISDIR(st.st_mode)) {
    if (!S_ISLNK(st.st_mode)) {
        list_dir(fullpath);
    }
}

总结

  • readdir 本身不支持递归
  • 递归逻辑要自己写
  • 必须处理 . / ..
  • 推荐 lstat + 判断 S_ISDIR

如果你需要:

  • 只统计文件数
  • 按深度限制递归
  • 多线程遍历
  • 类似 find 的功能

可以继续问我。

0 踩