You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux递归遍历子目录搜索文件的代码报错问题求助

解决递归搜索文件时遇到非目录文件报错的问题

我懂你现在的困扰——递归搜索文件的时候,一碰到非目录的文件程序就报错停住,加了S_ISREG判断也没搞定对吧?这问题其实出在判断逻辑顺序和文件路径处理上,咱们一步步来修正:

问题根源分析

你遇到的报错,本质是对非目录文件调用了opendir()——这个函数只能打开目录,对普通文件调用肯定会失败,触发perror。而你加的S_ISREG判断没起作用,大概率是这两个原因:

  1. 没有先拼接完整文件路径就调用stat(),导致获取文件属性失败,判断逻辑失效;
  2. 判断的方向错了:我们需要筛选出目录去递归打开,而不是判断普通文件——普通文件只需要检查文件名是否匹配即可,不需要去打开它。

修正后的完整代码

下面是调整后的代码,我会标注关键修改点:

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

// 递归搜索函数:参数为当前目录路径,目标文件名
void search_file(const char *base_path, const char *target) {
    char full_path[1024]; // 存储完整文件路径,可根据需求调整大小
    DIR *dir = opendir(base_path);
    struct dirent *entry;
    struct stat stat_buf;

    // 打开目录失败时,打印错误但不终止程序,继续搜索其他目录
    if (!dir) {
        perror("Error opening directory");
        return;
    }

    while ((entry = readdir(dir)) != NULL) {
        // 跳过当前目录(.)和上级目录(..),避免无限递归
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;

        // 拼接当前目录与子项的完整路径,这是关键!
        snprintf(full_path, sizeof(full_path), "%s/%s", base_path, entry->d_name);

        // 获取文件属性,失败则跳过该文件,继续处理下一个
        if (stat(full_path, &stat_buf) == -1) {
            perror("Error getting file stat");
            continue;
        }

        // 如果是目录,递归搜索该子目录
        if (S_ISDIR(stat_buf.st_mode)) {
            search_file(full_path, target);
        } 
        // 如果是普通文件,检查是否是目标文件
        else if (strcmp(entry->d_name, target) == 0) {
            printf("Found target file: %s\n", full_path);
        }
    }

    closedir(dir);
}

int main(int argc, char *argv[]) {
    // 检查参数是否正确:需要传入起始目录和目标文件名
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <start_directory> <target_filename>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // 调用递归搜索函数
    search_file(argv[1], argv[2]);

    return 0;
}

关键修改说明

  • 完整路径拼接:用snprintf把当前目录和子项名称拼成完整路径,确保stat()和递归调用时能正确定位文件;
  • 正确的类型判断:用S_ISDIR筛选目录,只有目录才会递归调用opendir(),普通文件只做文件名匹配;
  • 容错处理:打开目录或获取文件属性失败时,用return或continue跳过,而不是直接终止程序,保证其他目录的搜索能继续;
  • 跳过特殊目录:必须跳过.和..,否则会陷入无限递归。

这样修改后,程序就不会因为碰到普通文件而报错停止,能正常递归遍历所有子目录并找到目标文件啦。

内容的提问来源于stack exchange,提问作者sylar12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:29:03