C语言递归计算嵌套目录文件总块大小时子目录文件块大小为0
问题原因与修复方案
核心问题
你调用lstat获取文件块大小时,仅传入了文件名filenum->d_name,没有拼接当前正在遍历的目录路径:
- 首层目录遍历正常是因为你传入的初始路径和进程当前工作目录一致,仅传文件名可以找到对应文件
- 嵌套子目录遍历时,没有拼父目录路径的文件名无法被
lstat定位到,属性查询失败不会计入总大小,因此嵌套目录内文件返回的块大小均为0
修复后的代码
#include <stdio.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> #include <stdlib.h> #include <limits.h> int scanDir (char *fstring) { char path_buf[PATH_MAX] = { 0 }; int total_size = 0; DIR *dir = opendir(fstring); if(dir == NULL) { perror("Could not open directory"); exit(EXIT_FAILURE); } struct dirent *filenum; while((filenum = readdir(dir)) != NULL) { // 跳过当前目录和上级目录标识 if (strcmp(filenum->d_name, ".") == 0 || strcmp(filenum->d_name, "..") == 0) { continue; } // 统一拼接全路径 snprintf(path_buf, sizeof(path_buf), "%s/%s", fstring, filenum->d_name); if (filenum->d_type == DT_DIR ) { total_size += scanDir(path_buf); } else { struct stat buf; int res = lstat(path_buf, &buf); if (res == 0){ total_size += buf.st_blocks; printf("%s: %ld\n", path_buf, buf.st_blocks); } } memset(path_buf, 0, sizeof(path_buf)); } closedir(dir); return total_size; }
优化说明
- 统一拼接全路径后再做属性查询或目录递归,修复路径找不到的问题
- 用系统定义的
PATH_MAX作为路径缓冲区长度,避免长路径溢出 - 用
snprintf替代多次strcat拼接路径,写法更简洁安全 - 调整判断逻辑减少代码嵌套层级,可读性更高
内容的提问来源于stack exchange,提问作者noob_coder
相关产品推荐
相关产品推荐

