Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.98/55: Рейтинг темы: голосов - 55, средняя оценка - 4.98
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464

Определить тип файла (файл, папка и т.д.) и его размер

15.03.2014, 13:16. Показов 10434. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пробую это сделать следующим образом:
Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
 
int main(int argc, char *argv[])
{
    DIR *directory;
    struct dirent *dirdata;
    struct stat   filestat;
 
    directory=opendir(argv[1]);
 
    while(dirdata=readdir(directory))
    {
        stat(dirdata->d_name, &filestat);
        printf("%ld ", filestat.st_size);
        printf("%s\n", dirdata->d_name);
    }
 
    return 0;
}


В результате выполнения программы получается, что все файлы и папкаи в argv[1] имеет одинаковый размер (4096), а один из файлов имеет нулевой размер. При определении типа (st_rdev) все файлы имеет 0-ой тип.

Подскажите, что не так?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.03.2014, 13:16
Ответы с готовыми решениями:

Определить размер файла А, если файл пуст то удалить его, иначе вывести 100 байтов содержимого на экран
Определить размер файла А, Если файл пуст то удалить его, иначе вывести 100 байтов содержимого на экран. Ассемблер

Определить тип файла, дата загрузки, размер
Здравствуйте. Подскажите, пожалуйста, как для предложенного интерфейса сделать, чтобы вместо строк, обведенных красной линией, определялся...

Поток: открыть любой файл, определить его размер и занести в новый файл
очень нужно решить две задачи 1.Создать поток открывающий любой файл,определить его размер и занести в новый файл. 2.Создать...

2
209 / 183 / 114
Регистрация: 15.03.2014
Сообщений: 398
19.03.2014, 06:49
galaid, в двух словах - один из вариантов решения - рекурсивно обходить все вложенные директории и суммировать размеры файлов в них. Набросал код на скорую руку.

Данный код только пример чтобы показать вариант решения твоей задачи.
В моем примере для краткости предусмотрена обработка только некоторых ошибок.
Для понимания примера рекомендую прочесть Нэйл Мэтью, Ричард Стоунс Основы программирования в Linux 4-е издание 2009 год.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
 
// посчитать размер afqkf 
long long calc_size_file( char* dir );
// вывевсти на экран тип, размер, имя файлов из указанной директории
void print_dir( char* dir );
// определить тип файла 
char display_file_type ( int st_mode );
 
 
int main( int argc, char* argv[] ) {
 
    if ( argc != 2 ) { // если неверно задан аргумент
        // выводим сообщение об ошибке
        fprintf( stderr, "Invalid argument! Use: viewdir <directory>\n" );
        return EXIT_FAILURE; // выходим из программы
    }
    // выводим сообщение о том какую директорию сканируем
    printf( "Directory scan of  %s\n", argv[ 1 ] ); 
    print_dir( argv[ 1 ] ); // выводим на экран тип, размер, имя файлов указанной директории
    printf( "done.\n" );
    return EXIT_SUCCESS;
}
 
void print_dir( char* dir ){
    DIR *dp; // поток каталога
    struct dirent *entry; // для имени и индекса файла
    struct stat statbuf; // для информации о файле
 
    if ( ( dp = opendir( dir ) ) == NULL ) { // если не смогли открыть поток каталога
        fprintf( stderr, "cannot open directory: %s\n", dir ); // выводим сообщение об ошибке
        return; // выходим из функции
    }
 
    chdir( dir ); // перемещаемся в указанную директорию
 
    while ( ( entry = readdir( dp ) ) != NULL ) { // цикл по всем файлам указанной директории
        lstat( entry->d_name, &statbuf ); // считываем информацию о файле в структуру
 
        if ( S_ISDIR( statbuf.st_mode ) ) { // если это директория
 
            // проверяем является ли она . или .. 
            if ( strcmp( ".", entry->d_name ) == 0 ||
                    strcmp( "..", entry->d_name ) == 0 ) // и если да,
                continue; // то игнорируем ее, возвращаясь в начало цикла
 
            // считаем размер директории      
            long long size = calc_size_file( entry->d_name );
 
            // если размер посчитать не удалось, то
            if ( size == -1 )
                printf ( "%c\t%s\t\t%s\n", 'd', "unknow", entry->d_name ); // выводим на экран информацию об этом
            else // а если все в порядке
                // выводим информацию о директории
                printf( "%c\t%lld\t\t/%s\n", 'd', ( long long )statbuf.st_size + size, entry->d_name );
        }
        else{ // иначе - если это НЕ директория, то выводим информацию о файле
            printf( "%c\t%lld\t\t/%s\n", display_file_type( statbuf.st_mode ), ( long long )statbuf.st_size, entry->d_name );
        }
    }
 
    closedir( dp ); // закрываем указаннню директорию
}
 
long long calc_size_file( char* dir ) {
 
    static int err_code = 0; // для запоминания ошибки
    long long  sum_size = 0; // для размера файла
 
    DIR *dp; // поток каталога
    struct dirent *entry; // для имени и индекса файла
    struct stat statbuf; // для информации о файле
 
    if ( ( dp = opendir( dir ) ) == NULL ) {  // если не смогли открыть поток каталога
        err_code = 1; // запоминаем это
        return -1;
    }
 
    // а если все нормально, то
    chdir( dir );  // перемещаемся в указанную директорию
    // цикл по всем файлам указанной директории
    while ( ( entry = readdir( dp ) ) != NULL && !err_code) { 
        lstat( entry->d_name, &statbuf ); // считываем информацию о файле в структуру
 
        if ( S_ISDIR( statbuf.st_mode ) ) { // если это директория
 
            // проверяем является ли она . или ..
            if ( strcmp( ".", entry->d_name ) == 0 ||
                    strcmp( "..", entry->d_name ) == 0 ) // и если да,
                continue; // то игнорируем ее, возвращаясь в начало цикла
 
            // прибавляем к общему размеру размер текущей директории
            // ( 4096 -  обычно такой размер имеют директории, но если в директории МНОГО данных, то размер может быть и больше )
            // далее считаем размер всех файлов, содержащихся в текущей директории и прибавляем к общему размеру
            // а чтобы посчитать - РЕКУРСИВНО вызововем нашу функцию и т.о. спустимся на уровень ниже 
            sum_size += ( long long )statbuf.st_size + calc_size_file( entry->d_name ); // РЕКУРСИЯ
 
            if ( err_code ) // если была ошибка,
                return -1; // то завершаем функцию с ошибочным кодом возврат
 
        }
        else{ 
            // иначе - если это НЕ директория, то прибавляем к общему размеру текущей директории размер данного файла 
            sum_size += ( long long )statbuf.st_size;
        }
    }
 
 
    // после того как закончили считать размер очередной директории - перемещаемся на уровень выше
    // т.е. в предыдущию директорию
    chdir( ".." );
    closedir( dp ); // закрываем поток каталога
 
    return sum_size; // а если все нормально, то возвращаем искомый размер
}
 
char display_file_type ( int st_mode ) {                                   
    // тут все ясно
    switch ( st_mode & S_IFMT ) {
        case S_IFDIR:  
            return 'd';
        case S_IFCHR:  
            return 'c'; 
        case S_IFBLK:  
            return 'b'; 
        case S_IFREG:
            return 'r';
        case S_IFLNK: 
            return 'l';
        case S_IFSOCK:
            return 's';
        case S_IFIFO:
            return 'f';
        default:
            return 'u';
    }
    return;
}
Примеры работы приложения на скриншоте.
Миниатюры
Определить тип файла (файл, папка и т.д.) и его размер  
1
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464
19.03.2014, 19:08  [ТС]
BlackSpace, спасибо. В принципе разобрался уже сам. Но все равно спасибо за наглядный пример.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.03.2014, 19:08
Помогаю со студенческими работами здесь

Определить файл или папка в параметрах запуска bat-файла
Здравствуйте, форумчане! Есть такая задача: Написать bat-файл, параметрами которого являются имена файлов или каталогов...

Определить размер файла, и если этот размер меньше определенного, скопировать этот файл в другой каталог
Задача: определить размер файла по указанному пути, и если этот размер меньше определенного скопировать этот файл в другой каталог. ...

Определить тип файла, не зная его расширения
делаю программу,которая пересохраняет файлы.так вот,как сделать проверку на то,что это звуковой файл(не по расширению файла)

Дан файл целых чисел. Удвоить его размер, дописав в конец содержимое файла (в том же порядке)
Дан файл целых чисел. Удвоить его размер, дописав в конец содержимое файла (в том же порядке). Описывать файл вот так:f: text;

Дан файл целых чисел. Удвоить его размер, дописав в конец содержимое файла (в том же порядке)
Дан файл целых чисел. Удвоить его размер, дописав в конец содержимое файла (в том же порядке).


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru