Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/75: Рейтинг темы: голосов - 75, средняя оценка - 4.65
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526

Перебор файлов в каталоге (включая вложенные каталоги)

01.03.2012, 18:07. Показов 14461. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Столкнулся с такой проблемой.
Язык Си.
Как перебирать все файлы в каком-либо каталоге(включая вложенные каталоги)?
Как определить: есть ли доступ к данному вложенному каталогу или файлу на каждом шаге перебора?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.03.2012, 18:07
Ответы с готовыми решениями:

[boost::filesystem] Как пройтись по каталогу, включая вложенные каталоги ?
Доброго времени суток. Нужно скопировать в вектор все файлы в каталоге, включая файлы, находящиеся во вложенных каталогах. ...

перебор файлов в каталоге
Привет всем. Пытаюсь осуществить перебор файлов в определенном каталоге: ...

Определение суммарного размера файлов в папке, включая вложенные папки
Смысл таков... Может кто то встречал класс с методом или свойством для того чтобы вывести количество байт занимаемой папкой со вложенными...

13
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
01.03.2012, 18:11
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Цитата Сообщение от go Посмотреть сообщение
Как перебирать все файлы в каком-либо каталоге
readdir, scandir
Цитата Сообщение от go Посмотреть сообщение
есть ли доступ к данному вложенному каталогу или файлу
access
2
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
01.03.2012, 18:25  [ТС]
Цитата Сообщение от Vourhey Посмотреть сообщение
scandir
А во вложенные каталогах он тоже сам залезает?

Добавлено через 1 минуту
И что она будет делать, если к какому-то каталогу нет доступа?

Добавлено через 27 секунд
Цитата Сообщение от Vourhey Посмотреть сообщение
readdir,
Уже пробовал ее. Не получилось с ней обойти.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
01.03.2012, 18:40
Цитата Сообщение от go Посмотреть сообщение
А во вложенные каталогах он тоже сам залезает?
нет, просто вызывай ее рекурсивно для всех полученных каталогов из списка
Цитата Сообщение от go Посмотреть сообщение
И что она будет делать, если к какому-то каталогу нет доступа?
проверяй перед вызовом с помощью access
Цитата Сообщение от go Посмотреть сообщение
Уже пробовал ее. Не получилось с ней обойти.
где код?
1
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
01.03.2012, 18:42
Цитата Сообщение от go Посмотреть сообщение
Уже пробовал ее. Не получилось с ней обойти.
А функция тут при чем? Все дело в тебе. Пиши тут код, скажут, где ошибка
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
01.03.2012, 18:43
В книжке «UNIX. Профессиональное программирование» (У. Стивенс, С. Раго) есть отличный пример для рекурсивного обхода дерева каталогов в разделе 4.21. Можно сказать, там уже готовый код для твоей задачи.
1
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
01.03.2012, 19:06  [ТС]
Цитата Сообщение от Nameless One Посмотреть сообщение
где код?
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
#include <stdio.h>
#include <dirent.h>
#include <stdlib.h>
 
void cmp(DIR *, DIR *);
 
int main(int argc, char *argv[])
{
        DIR *d1, *d2;
        
        if ( !(d1 = opendir(argv[1])) || ! (d2 = opendir(argv[2])) || argc < 3 )
        {
                fprintf(stderr, "$s: error dir or arg\n", argv[0]);
                exit(1);
        }
 
        cmp(d1, d2);
 
        return 0;
}
 
void cmp(DIR *d1, DIR *d2)
{
        struct dirent *f1;
        struct dirent *f2;
        
        while ( (f1 = readdir(d1)) )
        {
                if ( f1->d_type == DT_DIR )
                {
                        DIR *t1;
                        if ( (t1 = opendir(f1->d_name)) )
                                cmp(t1, d2);
                }
                else
                {
                        while ( (f2 = readdir(d2)) )
                        {
                                if ( f2->d_type == DT_DIR )
                                {
                                        DIR *t2;
                                        if ( (t2 = opendir(f2->d_name)) )
                                                cmp(d1, t2);
                                }
                                else
                                        printf("%s - %s\n", f1->d_name, f2->d_name);
                        }
                }
        }   
}
Перебираю для сравнения в двух каталогах

Добавлено через 25 секунд

Не по теме:

Цитата Сообщение от Vourhey Посмотреть сообщение
Все дело в тебе.
ну это ясно ведь ;)



Добавлено через 11 минут
Nameless One, в книге
C
1
2
3
4
5
struct dirent {
ino_t d_ino; /* номер индексного узла */
char d_name[NAME_MAX +1]; /* строка имени файла, завершающаяся */
/* нулевым символом */
}
http://www.delorie.com/gnu/doc... c_270.html здесь иначе написано или нет(или я не правильно перевел)?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.03.2012, 07:17
Цитата Сообщение от go Посмотреть сообщение
Nameless One, в книге...
в книге описаны только те поля, которые обязательно должны присутствовать в структуре (то же самое пишет и "man dirent.h", "man 3 readdir" добавляет еще три поля). Конкретная реализация может добавлять дополнительные поля.

Вот набросал функцию обхода дерева каталогов:
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
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
 
typedef int           /* 1 в случае ошибки, 0 в прот. случае */
(*PFUNC)(const char*,         /* обрабатываемый файл */
     const struct stat*); /* информация о файле */
 
int             /* 1 в случае ошибки, 0 в прот. случае */
walk(const char*,       /* начальная директория */
     PFUNC,         /* функция, которая вызывается для каждого
                   элемента директории */
     int);          /* вызывать функцию для каталогов? */
 
int print_entry(const char* name, const struct stat* st)
{
    printf("%s%s\n", name,
       /* добавляем "/" к именам каталогов при выводе
        * для наглядности
        */
       (S_ISDIR(st->st_mode) ? "/" : ""));
 
    return 0;
}
 
int main(int argc, char* argv[])
{
    if(argc != 2)
    {
    fprintf(stderr, "Usage: %s DIR\n", argv[0]);
    exit(1);
    }
 
    /* печать всего дерева каталогов, начиная
     * с argv[1] (каталоги тоже печатаются)
     */
    exit(walk(argv[1], print_entry, 1));
}
 
/* делаем глобальной переменной, чтобы не допустить разрастания
 * стека при рекурсивных вызовах (рекурсия-то древовидная)
 */
char buf[PATH_MAX];
 
int walk(const char* dirname, PFUNC pfunc, int do_dirs)
{
    DIR* dp;
    struct stat st;
    struct dirent* dirp;
    int retval = 0;
 
    size_t len = strlen(dirname);
 
    if((dp = opendir(dirname)) == NULL)
    {
    perror(dirname);
    return 1;
    }
 
    strncpy(buf, dirname, len);
 
    while((dirp = readdir(dp)) != NULL)
    {
    if(strcmp(dirp->d_name, ".") == 0 ||
       strcmp(dirp->d_name, "..") == 0)
        continue;
 
    buf[len] = '/';
    buf[len+1] = '\0';
 
    strcat(buf, dirp->d_name);
    
    if(lstat(buf, &st) == -1)
    {
        perror(dirp->d_name);
        retval = 1;
        break;
    }
 
    if(S_ISDIR(st.st_mode))
    {
        if(do_dirs)
        {
        if(pfunc(buf, &st) == 1)
        {
            retval = 1;
            break;
        }
        }
                
        if(walk(buf, pfunc, do_dirs) == 1)
        {
        retval = 1;
        break;
        }
        
    }
    else if(pfunc(dirp->d_name, &st) == 1)
    {
        retval = 1;
        break;
    }
 
    buf[len] = '\0';
    }
 
    closedir(dp);
    return retval;
}
2
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
04.03.2012, 13:43  [ТС]
Цитата Сообщение от Nameless One Посмотреть сообщение
int walk(const char* dirname, PFUNC pfunc, int do_dirs)
Для чего необходим третий аргумент?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
04.03.2012, 14:11
go, он указывает что нужно вызывать функцию pfunc не только для обычных файлов, но и для каталогов.
Т.е., пусть у нас есть такое дерево каталогов:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
[nameless@desktop tree]$ tree . -F --charset HTML
.
|-- topdir1/
|   |-- file
|   `-- subdir/
|       `-- file
`-- topdir2/
    |-- file
    `-- subdir/
        `-- file
 
4 directories, 4 files
[nameless@desktop tree]$
Обходим текущий "." каталог. Если параметр do_dirs равен нулю, то мы обрабатываем только файлы в дереве каталогов, т.е. функция будет вызвана только для всех file. Если же он ненулевой, то в дополнении к файлам функция будет вызвана для всех подкаталогов: topdir1, topdir2, topdir1/subdir, topdir2/subdir.

А вообще, почему бы не запустить эту функцию самому с разными значениями этого параметра? Быстро и наглядно.
1
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
04.03.2012, 17:06
Nameless One, простите, но глаза режет
C
1
2
3
4
        buf[len] = '/';
        buf[len+1] = '\0';
 
        strcat(buf, dirp->d_name);
2TC: за Вас уже все написали man ftw
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
04.03.2012, 17:10
g_u_e_s_t, и это даже не мой код, а немного переработанный пример из книги, хотя соглашусь, выглядит кривовато
0
go
Эксперт С++
3646 / 1378 / 243
Регистрация: 16.04.2009
Сообщений: 4,526
06.03.2012, 19:56  [ТС]
Цитата Сообщение от Nameless One Посмотреть сообщение
if(strcmp(dirp->d_name, ".") == 0 ||
* * * * * *strcmp(dirp->d_name, "..") == 0)
Я так понимаю это пропуск текущего каталога. Не могли бы Вы объяснить, когда может возникнуть в этом необходимость? Ума не приложу для чего это.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
07.03.2012, 11:48
go, "." и ".." обозначают текущий и родительский каталоги, соответственно. Очевидно, что нет смысла вызывать рекурсивную обработку текущего каталога, т.к. его элементы уже обрабатываются в данный момент в данном рекурсивном вызове. Также очевидно, что обрабатывать родительский каталог тоже не нужно.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.03.2012, 11:48
Помогаю со студенческими работами здесь

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

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

Перебор циклом файлов в каталоге
Доброго времени суток. Как пройтись циклом по файлам в папке?

Перебор файлов в каталоге - групповое редактирование
Есть файлы такого типа Расположены они к примеру с:\temp 1 файл.xls 2 файл.xls 3 файл.xls 4 файл.xls 5 файл.xls Как мне их...

Перебор в цикле с FOR файлов в каталоге с русским именем
Команда перебора файлов не проходит set Chain = D:\seva\Отдел ИО\Работы\Программы for %%A in (&quot;%Chain%\*.txt&quot;) do (echo...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru