如何递归浏览文件夹并计算总文件大小?

时间:2018-04-30 17:16:45

标签: c file recursion directory

我试图递归地进行这项工作,所以当它找到一个文件夹进入文件夹并找到文件大小时,最后打印所有文件大小的总和。但是,我无法弄清楚如何以递归方式工作,我尝试了很多东西。即使我没有进行递归,我的总计数也没有正确结束。非常感谢任何和所有的帮助。

LOCAL_QUORUM

2 个答案:

答案 0 :(得分:1)

如果文件名构建工作已按建议工作,那么全局

int total = 0;

不足以将文件大小与

相加
total += (int)info.st_size;

所以我建议

uint64_t total;

然后

total += info.st_size;

除了全局是一种糟糕的做法,可以通过从递归函数中返回一个值来改进它。然后总数可以在递归函数中求和。

uint64_t do_ls(char[]);

答案 1 :(得分:0)

当您有一个要递归的目录条目时,您必须通过将目录和条目名称与/分隔符连接起来构建路径,并递归调用do_ls

为了计算文件大小,您可以使用stat系统调用,但是您也需要路径名,因此在测试条目类型之前构造是(使用malloc来分配空间连接的字符串)并且在使用后不要忘记释放它。

同时忽略...条目,并将closedir()移出while循环。

这是一个不使用全局变量的改进版本 total大小,而是将累积大小返回给调用者:

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

long long do_ls(const char *name) {
    DIR *dir_ptr;
    struct dirent *direntp;
    struct stat info;
    long long total = 0;
    int output = 1;

    if (stat(name, &info)) {
        fprintf(stderr, "ls01: cannot stat %s\n", name);
        return 0;
    }
    if (S_ISDIR(info.st_mode)) {
        if ((dir_ptr = opendir(name)) == NULL) {
            fprintf(stderr, "ls01: cannot open directory %s\n", name);
        } else {
            while ((direntp = readdir(dir_ptr)) != NULL) {
                char *pathname;

                /* ignore current and parent directories */
                if (!strcmp(direntp->d_name, ".") || !strcmp(direntp->d_name, ".."))
                    continue;

                pathname = malloc(strlen(name) + 1 + strlen(direntp->d_name) + 1);
                if (pathname == NULL) {
                    fprintf(stderr, "ls01: cannot allocated memory\n");
                    exit(1);
                }
                sprintf(pathname, "%s/%s", name, direntp->d_name);
                total += do_ls(pathname);
                free(pathname);
            }
            closedir(dir_ptr);
        }
    } else {
        total = info.st_size;
    }
    printf("%10lld  %s\n", total, name);
    return total;
}

int main(int ac, char *av[]) {
    int i = 1;

    if (i >= ac) {
        do_ls(".");
    } else {
        long long total = 0;
        while (i < ac) {
            total += do_ls(av[i++]);
        }
        printf("total is: %lld\n", total);
    }
    return 0;
}