Как мне рекурсивно просматривать папки и подсчитывать общий размер файла? - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь заставить это работать рекурсивно, поэтому, когда он находит папку, он попадает в папку и находит размер файла, а затем в конце выдает сумму всех размеров файла. Однако я не могу понять, как заставить это работать рекурсивно, я перепробовал много вещей. Кроме того, мой общий счет не всегда корректен, даже когда я не делаю рекурсию. Любая помощь очень ценится.

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

void do_ls(char[]);
int total = 0;

int main(int ac, char *av[])
{
    if (ac == 1)
        do_ls(".");
    else
    {
        while (--ac) {
            printf("%s:\n", *++av);
            do_ls(*av);
        }
    }
}

void do_ls(char dirname[])
{
    DIR *dir_ptr;
    struct dirent *direntp;
    struct stat info;

    if ((dir_ptr = opendir(dirname)) == NULL)
        fprintf(stderr, "ls01: cannot opern %s\n", dirname);
    else
    {
        while((direntp = readdir(dir_ptr)) != NULL) {
            stat(direntp->d_name, &info);
            if (S_ISDIR(info.st_mode))
                printf("%s\n", direntp->d_name);
                //I believe recursion goes here, I tried the following 
                //do_ls(direntp->d_name);
                //do_ls(".");
                //do_ls(dirname + '/' + direntp->d_name);
                //none of these seemed to work.
            else
                printf("%d %s\n", (int)info.st_size, direntp->d_name);
                total += (int)info.st_size;
        }
        closedir(dir_ptr);
    }
    printf("Your total is: %d \n", total);
}

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Если у вас есть сборка файлов, работающая, как уже советовали, глобальная

int total = 0;

недостаточно для суммирования размера файлов с

total += (int)info.st_size;

поэтому я предлагаю

uint64_t total;

, а затем

total += info.st_size;

Кроме того, глобальная практика - это плохая практика, которую можно улучшить, возвращая значение из рекурсивной функции, когда оно работает. Итог может быть суммирован в рамках рекурсивной функции.

uint64_t do_ls(char[]);
0 голосов
/ 30 апреля 2018

Если у вас есть запись в каталоге для рекурсии, вы должны создать путь путем объединения каталога и имени записи с разделителем / и рекурсивным вызовом do_ls.

Чтобы вычислить размеры файлов, вы можете использовать системный вызов stat, но вам также понадобится и путь, поэтому конструкция перед проверкой на тип записи (используйте malloc, чтобы выделить место для объединенной строки) и не забудьте освободить его после использования.

Также игнорируйте записи . и .. и выведите closedir() из цикла while.

Вот улучшенная версия, которая не использует глобальную переменную для total size, но вместо этого возвращает совокупный размер вызывающей стороне:

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...