Посчитать размер файлов в текущем поддереве

Посчитать размер файлов в текущем поддереве

21.05.2015 05:26:52 Просмотров 20 Источник

Помогите найти ошибку. Не пойму в чём дело. Сама задача стоит такая: нужно посчитать размер файлов в текущем поддереве. Она считает размер файлов, но когда я начинаю проверять (сам на калькуляторе всё пересчитываю) у меня получаются другие результаты. Пол дня на ней потратил, не могу понять где ошибся. Программу пишу под Unix.

//Подключаем необходимые библиотеки
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

int dcheck(char *dname)
{
    struct stat stbuf;      //Атрибуты элемента
    struct dirent *entry;       //Элемент каталога
    DIR *d;             //Дескриптор дериктории
    //Переменная, содержащая путь к проверяемым файлам и папкам
    char *cur_ent = malloc(sizeof(char)); 
    int count = 0;
    //Получаем дескриптор, переданной в функцию, директории
    if ((d = opendir(dname)) != NULL)
    {
        //Получаем по очереди все элементы директории и проверяем их
        while((entry = readdir(d)) != NULL)
        {
    //Если попалась запись начинающиеся на . или .. пропускаем ее
            if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
                continue;
    //Копируем в переменную cur_ent название директории
            strcpy(cur_ent, dname);
    //Вставляем символ разделителя директории
            strcat(cur_ent,"/");
    //Добавляем имя элемента
            strcat(cur_ent, entry->d_name);
    // Получаем атрибуты текущей записи
            stat(cur_ent, &stbuf);
    //Проверяем является ли текущая запись папкой
            if(!((stbuf.st_mode & S_IFMT) == S_IFDIR))
            {
             count+= stbuf.st_size;
            }
        }
   //Иначе закрываем дескриптор и возвращаем значение 0
        closedir(d);
    }
    return count;
}

int main(void)
{
    int count = 0;
    DIR *d;
    struct dirent *entry;
    struct stat stbuf;
    // Получаем дескриптор текущей директории
    d = opendir("."); 
    //Получаем по очереди все элементы директории и проверяем их
    while ((entry = readdir(d)) != NULL)
    {
        //Если попалась запись начинающиеся на . или .. пропускаем ее
        if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
            continue;
        // Получаем атрибуты текущей записи
        stat(entry->d_name, &stbuf);
        if((stbuf.st_mode & S_IFMT) == S_IFDIR)
        {
            //Если да, то передаем имя этой директории в функцию dcheck
            count+=dcheck(entry->d_name);
        }
        //Проверяем является ли текущая запись папкой
        if(!((stbuf.st_mode & S_IFMT) == S_IFDIR))
        {
         count+= stbuf.st_size;
        }     
    }
     // Закрываем дескриптор
    closedir(d);
    printf("%d\n", count);
    return 0;
}
У вопроса есть решение - Посмотреть?

https://ru.stackoverflow.com/questions/425331/%d0%9f%d0%be%d1%81%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-%d0%b2-%d1%82%d0%b5%d0%ba%d1%83%d1%89%d0%b5%d0%bc-%d0%bf%d0%be%d0%b4%d0%b4%d0%b5%d1%80%d0%b5%d0%b2%d0%b5#comment433552_425331
А размеры файлов случайно не больше пары гигабайт? Попробуйте для начала создать каталог, в котором один-два файла размером в килобайт-два и проверить работу.
https://ru.stackoverflow.com/questions/425331/%d0%9f%d0%be%d1%81%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-%d0%b2-%d1%82%d0%b5%d0%ba%d1%83%d1%89%d0%b5%d0%bc-%d0%bf%d0%be%d0%b4%d0%b4%d0%b5%d1%80%d0%b5%d0%b2%d0%b5#comment433555_425331
Приведите пример вывода размера файлов стандартной утилитой linux и размера, который получается в результате исполнения Вашей программы.
https://ru.stackoverflow.com/questions/425331/%d0%9f%d0%be%d1%81%d1%87%d0%b8%d1%82%d0%b0%d1%82%d1%8c-%d1%80%d0%b0%d0%b7%d0%bc%d0%b5%d1%80-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2-%d0%b2-%d1%82%d0%b5%d0%ba%d1%83%d1%89%d0%b5%d0%bc-%d0%bf%d0%be%d0%b4%d0%b4%d0%b5%d1%80%d0%b5%d0%b2%d0%b5#comment433557_425331
KoVadim, нет, там все файлы малых размеров, я считал на калькуляторе, там примерно размер всех файлов 34к байт.

Ответы - Посчитать размер файлов в текущем поддереве / Посчитать размер файлов в текущем поддереве

Является ответом!
user6550

21.05.2015 07:03:17

Для начала - вы всё слишком усложнили. Слово "рекурсия" незнакомо? Не говоря уж о бессмысленном и беспощадном обращении с памятью внутри (бесполезной) dcheck() и прочих радостях. Давайте я набросаю на коленке простенький вариант покороче, а вы сами попытаетесь понять где накосячили :)

P.S. Всякие мелочи опущены, для наколенного варианта сойдёт и так.

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

static void pfx( size_t level, const char * title, const char * name )
{
    while( level-- ) printf( " " );
    printf( "%-4s: %s\n", title, name );
}

static unsigned long calc_size( size_t level, const char * dirname )
{
    DIR *d;
    struct dirent *entry;
    struct stat stbuf;
    unsigned long total = 0;
    char ename[ PATH_MAX+1 ];

    pfx( level, "DIR", dirname );

    d = opendir( dirname );
    while( d && (entry = readdir(d)) )
    {
        if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
            continue;

        sprintf( ename, "%s/%s", dirname, entry->d_name);
        stat( ename, &stbuf );

        if( S_ISDIR(stbuf.st_mode) )
        {
            total += calc_size( level+1, ename );
        }
        else
        {
            pfx( level+1, "FILE", ename );
            total += stbuf.st_size;
        }
    }
    if( d ) closedir( d );
    return total;
}

int main()
{
    printf( "%lu\n", calc_size( 0, "." ) );
    return 0;
}
Закрыть X