Linux下C语言递归打印指定大小以下文件的异常问题
解决Linux下C语言递归遍历打印指定大小以下文件的问题
嘿,我碰到过好几个类似的递归遍历问题,你的代码大概率是在处理子目录时犯了两个常见错误之一:要么递归调用时没把size_smaller参数传进去,要么错误地对目录本身做了大小过滤。让我给你拆解下问题,再给你修复好的代码。
问题根源分析
- 递归调用漏传参数:如果你的原代码在进入子目录时,调用
list_recursive没带size_smaller,那子目录里的文件根本不会做大小判断,自然不会输出符合条件的内容。 - 错误过滤目录:要是你把目录也纳入了大小判断逻辑,比如目录本身的大小超过阈值就跳过递归,那子目录里的文件直接就没机会被遍历到了——我们要的是检查目录里的文件,不是目录本身的大小!
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> #include <limits.h> // 用于PATH_MAX void list_recursive(char* path, long long size_smaller) { DIR *dir = opendir(path); if (!dir) { perror("Failed to open directory"); return; } struct dirent *entry; while ((entry = readdir(dir)) != NULL) { // 跳过当前目录和上级目录,避免无限递归 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } // 拼接完整文件路径 char full_path[PATH_MAX]; snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name); struct stat stat_info; if (lstat(full_path, &stat_info) == -1) { perror("Failed to get file stats"); continue; } // 如果是目录,直接递归进去,不管目录大小 if (S_ISDIR(stat_info.st_mode)) { list_recursive(full_path, size_smaller); // 关键:必须传递size_smaller参数! } // 如果是普通文件,检查大小是否符合要求 else if (S_ISREG(stat_info.st_mode)) { if (size_smaller == -1 || stat_info.st_size < size_smaller) { printf("%s (Size: %lld bytes)\n", full_path, (long long)stat_info.st_size); } } } closedir(dir); } int main(int argc, char* argv[]) { if (argc != 3) { fprintf(stderr, "Usage: %s <target_directory> <max_size_bytes>\n", argv[0]); fprintf(stderr, "Use -1 as max_size to list all files\n"); return EXIT_FAILURE; } long long max_size = atoll(argv[2]); list_recursive(argv[1], max_size); return EXIT_SUCCESS; }
核心修复点说明
- 递归时传递大小阈值:在进入子目录调用
list_recursive时,明确把size_smaller传进去,这样子目录里的文件判断逻辑能和根目录保持一致。 - 区分目录与文件的处理逻辑:目录直接递归,不做大小判断;只有普通文件才会检查是否小于指定大小。
- 使用long long处理文件大小:
stat结构里的st_size是off_t类型,用long long转换可以避免大文件时的溢出问题。 - 完善错误处理:添加了
opendir和lstat的错误提示,方便排查问题。
测试方式
编译运行代码:
gcc -o small_files small_files.c # 打印指定目录下所有小于10KB的文件 ./small_files /home/your_user/documents 10240 # 打印所有文件(和原逻辑一致) ./small_files /home/your_user/documents -1
内容的提问来源于stack exchange,提问作者ISimion
相关产品推荐
相关产品推荐

