stat() дает неправильный размер каталога в c

Мне нужно найти размер файла или каталога, указанного в командной строке, с помощью stat(). Он отлично работает для файлов (как относительных, так и абсолютных путей), но когда я указываю каталог, он всегда возвращает размер 512 или 1024.

Если я распечатаю файлы в каталоге, это будет выглядеть следующим образом:

 Name : .
 Name : ..
 Name : new
 Name : new.c

но на самом деле там находятся только файлы new и new.c. Для этого размер возвращается как 512, даже если я помещаю в каталог больше файлов. Вот мой фрагмент кода:

if (stat(request.data,&st)>=0){
        request.msgType = (short)0xfe21;
        printf("\n Size : %ld\n",st.st_size);
        sprintf(reply.data,"%ld",st.st_size);
        reply.dataLen = strlen(reply.data);
    }
    else{
        perror("\n Stat()");
    }
}

Где я ошибся???

вот мой запрос, структура ответа:

 struct message{
        unsigned short msgType;
        unsigned int offset;
        unsigned int serverDelay;
        unsigned int dataLen;
        char data[100];
    };
struct message request,reply;

Я запускаю его в компиляторе gcc в ОС Unix.


person Sree    schedule 02.09.2012    source источник
comment
какая ОС/компилятор? также, что это за структура запроса/ответа?   -  person chacham15    schedule 03.09.2012
comment
Если вы поместите в каталог достаточно файлов, он станет больше 512 или 1024 байт. Например, если вы добавите 120 имен файлов, каждое из которых состоит из 10 или более символов, вы можете разумно ожидать, что их размер превысит 1024 байта.   -  person Jonathan Leffler    schedule 03.09.2012


Ответы (3)


stat() для каталога не возвращает сумму размеров файлов в нем. Поле размера показывает, сколько места занимает запись каталога, и оно зависит от нескольких факторов. Если вы хотите узнать, сколько места занимают все файлы в определенном каталоге, вам нужно выполнить рекурсию вниз по дереву, суммируя пространство, занимаемое всеми файлами. Вот как работают такие инструменты, как du.

person John Szakmeister    schedule 02.09.2012
comment
Ох, хорошо. Тогда я думаю, мне нужно проверить, является ли это каталогом, и если это так, то мне нужно сделать opendir() и readdir() для каждого файла и stat() отдельно. Я не знаю, как использовать du в программе на языке C. Это команда unix для определения использования диска в текущем каталоге..??? - person Sree; 03.09.2012
comment
Да, если это каталог, вам нужно выполнить opendir(), readdir() и stat() каждый файл в нем. Я не обязательно рекомендую использовать du из вашей программы на C... это был просто пример программы, использующей такой подход. - person John Szakmeister; 03.09.2012

Да. opendir() + цикл для readdir()/stat() даст вам размеры файлов/каталогов, которые вы можете суммировать, чтобы получить общее количество. Если у вас есть подкаталоги, вам также придется зацикливаться на них и файлах внутри них.

Чтобы использовать du, вы можете использовать функцию system(). Это только возвращает код результата вызывающей программе, чтобы вы могли сохранить результаты в файл, а затем прочитать файл. Код будет примерно таким,

system("du -sb dirname > du_res_file");

Затем вы можете прочитать файл du_res_file (при условии, что он был успешно создан), чтобы получить ответ. Это даст размер каталога + подкаталогов + файлов за один раз.

person Alec Danyshchuk    schedule 03.09.2012

Извините, я пропустил это в первый раз, stat дает только размер файлов, а не каталогов:

Эти функции возвращают информацию о файле. Для самого файла никаких разрешений не требуется, но в случае stat() и lstat() требуется разрешение на выполнение (поиск) для всех каталогов в пути, которые ведут к файлу.

Поле st_size дает размер файла (если это обычный файл или символическая ссылка) в байтах. Размер символической ссылки — это длина имени пути, которое она содержит, без завершающего нулевого байта.

посмотрите справочную страницу на fstat/stat

person chacham15    schedule 02.09.2012
comment
Но это (обычно) действительно дает размер каталога. Каталог Unix — это специальный файл. Например, мой домашний каталог имеет размер 4096 байт. (Это не имеет прямого отношения к размерам содержащихся в нем файлов.) - person Keith Thompson; 03.09.2012