Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
1

Как посчитать сколько на указанном пользователем диске всего файлов и папок?

03.10.2016, 17:28. Показов 1648. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Дело такое: нужно как-то посчитать сколько на указанном пользователе диске всего файлов и папок.

C++
1
2
3
4
5
6
7
8
9
10
11
CHAR NamesDIrectory[4200];
 
        NamesDIrectory[0] = UserNameDisk[0];
        NamesDIrectory[1] = ':';
        NamesDIrectory[2] = '\\';
        NamesDIrectory[3] = '\\';
        NamesDIrectory[4] = '*';
        NamesDIrectory[5] = '\0';
 
 
        poisk(NamesDIrectory); // Поиск файлов и папок
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
void poisk(LPCSTR NamesDIrectory)
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hf;
 
    int AmountDIRECTORY = 0;
    int AmountENCRYPTED = 0;
    int AmountNORMAL = 0;
 
 
 
 
 
    hf = FindFirstFile(NamesDIrectory, &FindFileData);
    if (hf != INVALID_HANDLE_VALUE)
    {
        do
        {
            if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
            {
/*
 
Тут будем творить чудеса
 
*/
                AmountDIRECTORY++;
            }
 
            //cout << FindFileData.cFileName << endl;
            //cout << FindFileData.dwFileAttributes << endl;
 
 
 
            
 
        } while (FindNextFile(hf, &FindFileData) != 0);
        FindClose(hf);
    }
 
    cout << "Папок в данном каталоге: " << AmountDIRECTORY << endl;
    
}
Идея была такова. При помощи функции FindFirstFile я могу просмотреть список файлов в указанном каталоге. Но она не считает файлы находящиеся в этих же папках. Делается все при помощи рекурсии. Т.е., когда атрибут файла - папка, начинается рекурсия, мы изменяем адрес, дописав в нем название папки, и так само проверяем что в ней есть. В плоть до того, пока в конечной папке не будет папок =). И делаем шаг назад.

Знаю, звучит трудно, может и глупо, но других вариантов в голу не пришло.
Если есть у кого идеи, или знает способ иной, то подскажите, буду рад легшему способу.

P.S. было бы хорошо, еще посчитать память, что занимают все файлы.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.10.2016, 17:28
Ответы с готовыми решениями:

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

Подскажите как получить список всех папок и файлов на диске С
Подскажите как получить список всех папок и файлов на диске С ?

Поиск файлов на диске, за исключением скрытых файлов и папок
Часть кода, желательно использовать её. DirectoryInfo Di = new DirectoryInfo(@&quot;F:&quot;); foreach...

Поиск указанных файлов на указанном диске и вывод результата на экран
Всем привет, я здесь впервые,и вот возник такой вопрос Для поиска файлов и выведения на экран я...

17
7787 / 6555 / 2983
Регистрация: 14.04.2014
Сообщений: 28,633
03.10.2016, 18:24 2
Ну а рекурсия, что, не работает?
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
03.10.2016, 19:14  [ТС] 3
Цитата Сообщение от nmcf Посмотреть сообщение
Ну а рекурсия, что, не работает?
Я то и подумал про нее, но разве нет легче способа?
0
7787 / 6555 / 2983
Регистрация: 14.04.2014
Сообщений: 28,633
03.10.2016, 19:54 4
Рекурсия - достаточно простой способ.
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
03.10.2016, 20:15 5
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
Если есть у кого идеи, или знает способ иной, то подскажите, буду рад легшему способу.
"Очевидное" решение - распарсить вывод df -i, исходя из идеи что каждый файл и папка кушают по одному inode.
Но если под Винду, на NTFS и без симлинков, то рекурсия.
1
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
04.10.2016, 21:23  [ТС] 6
Цитата Сообщение от Renji Посмотреть сообщение
Но если под Винду, на NTFS и без симлинков, то рекурсия.
Может кто подскажет как для сего сотворить рекурсию, а то с ними почти не работал =(
Принцип я то понял, но некоторые моменты не могу состыковать.
Например: начальный адрес у переменной "c:\\*", натыкается поисковик на папку, и добавляет имя папки к адресу, т.е. выйдет "c:\\папка\\*" , и так пойдем дальше пока не закончатся папки. После функция делает следующий шаг по предыдущему адресу или уже по измененному?
0
7787 / 6555 / 2983
Регистрация: 14.04.2014
Сообщений: 28,633
04.10.2016, 22:49 7
Цикл создаёшь по папкам в текущей и делаешь вызовы.
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
05.10.2016, 10:07 8
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
Может кто подскажет как для сего сотворить рекурсию, а то с ними почти не работал =(
Так и организовать. На входе у функции путь к обрабатываемой папке. Она идет по содержимому папки и плюсует счетчик файлов. Например, оформленный как глобальная переменная. Если функция натыкается на папку - вызывает саму себя с адресом папки. А потом едет по содержимому папки дальше.
Ну а код набивайте сами.
1
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
05.10.2016, 18:51  [ТС] 9
Цитата Сообщение от Renji Посмотреть сообщение
Если функция натыкается на папку - вызывает саму себя с адресом папки.
Я не могу понять как передать в функцию адрес папки на которую мы наткнулись, точнее сказать никакие действия не помогают. Ведь в начальную функцию мы передаем переменную типа чар,

C++
1
2
3
CHAR NamesDIrectory[4200];
 
poisk(NamesDIrectory);
Но функция FindFirstFile требует в качестве адреса переменную типа LPCSTR.
C++
1
void poisk(LPCSTR NamesDIrectory)
Есть идея, просто предыдущий адрес копировать в новую переменную и его объеденить с именем уже открытой папки, но не получается ни в какую все из-за константы =(
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
05.10.2016, 19:14 10
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
Есть идея, просто предыдущий адрес копировать в новую переменную и его объеденить с именем уже открытой папки, но не получается ни в какую все из-за константы =(
И какие проблемы с константой? Никто не запрещает использовать не константный объект там, где требуется константа. Нельзя делать наоборот.
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
05.10.2016, 20:19  [ТС] 11
Цитата Сообщение от Renji Посмотреть сообщение
И какие проблемы с константой? Никто не запрещает использовать не константный объект там, где требуется константа. Нельзя делать наоборот.
Вот попробовал сделать рекурсию. Сделал переменную в которую копирую имя старого пути + имя открытой папки. Потом передаю его в эту же самую функцию но получаю ошибку =(
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
void poisk(LPCTSTR NamesDIrectory)
{
    WIN32_FIND_DATA FindFileData;
    HANDLE hf;
 
    int AmountDIRECTORY = 0;
    int AmountENCRYPTED = 0;
    int AmountNORMAL = 0;
    char tymeName[30];
    int tymeA;
 
 
    hf = FindFirstFile(NamesDIrectory, &FindFileData);
    if (hf != INVALID_HANDLE_VALUE)
    {
        do
        {
            if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
            {
                
 
                for (int i = 0; i < 4201; i++)
                    {
                        //Копируем старый адресс в новую переменную до знака *
                        if (NamesDIrectory[i] != '*')
                        {
                            tymeName[i] = NamesDIrectory[i];
                        }
                        else
                        {
                            tymeName[i] = '\0';
                            tymeA = i;
                            break;
                        }
                    }
                
                
                for (int i = 0; i < 4201; i++)
                {       
                    //против корзины
                    if (FindFileData.cFileName[0] == '$')
                    {
                        tymeName[i] = '\0';
                        break;
                    }
                    
                    //добавляем к старому адресу имя папки
                    //
                    if (FindFileData.cFileName[i] != '\0')
                    {
                        tymeName[i + tymeA] = FindFileData.cFileName[i];
                    }
                    else
                    {
                        tymeName[i + tymeA] = '\\';
                        tymeName[i + 1 + tymeA] = '\\';
                        tymeName[i + 2 + tymeA] = '*';
                        tymeName[i + 3 + tymeA] = '\0';
                        break;
                    }
                } 
 
                ++AmountDIRECTORY;
                //cout << tymeName << endl;
                poisk(tymeName);
 
            }
 
            //cout << endl << FindFileData.cFileName << endl << endl;
            //cout << FindFileData.dwFileAttributes << endl;
 
 
 
            if (FindFileData.dwFileAttributes&FILE_ATTRIBUTE_NORMAL)
                AmountNORMAL++;
 
        } while (FindNextFile(hf, &FindFileData) != 0);
        FindClose(hf);
    }
 
    cout << "Папок в данном каталоге: " << AmountDIRECTORY << endl;
    
}
Миниатюры
Как посчитать сколько на указанном пользователем диске всего файлов и папок?  
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
05.10.2016, 20:28 12
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
нужно как-то посчитать сколько на указанном пользователе диске всего файлов и папок.
Получить вывод Dir в программу


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

а в случае с рекурсивным алгоритмом,
это неизбежно приведет к переполнению стека,
и краху программы.
0
59 / 59 / 53
Регистрация: 05.05.2013
Сообщений: 150
05.10.2016, 20:38 13
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
но получаю ошибку =(
у вас char tymeName[30] - массив в 30 элементов,
а в циклах максимальный индекс массива установлен в 4201,
там программа выходит за пределы массива и компилятор об этом говорит.
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
05.10.2016, 20:42  [ТС] 14
Цитата Сообщение от VAN0 Посмотреть сообщение
у вас char tymeName[30] - массив в 30 элементов,
Это уже исправил, сам уменьшил, и забыл вернуть

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
что программа впадет в вечный цикл.
программа ушла в никуда, я так понял пошло зацикливание
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
05.10.2016, 20:43 15
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
Вот попробовал сделать рекурсию. Сделал переменную в которую копирую имя старого пути + имя открытой папки. Потом передаю его в эту же самую функцию но получаю ошибку =(
Я же сказал - "нельзя делать наоборот". Ваша функция должна принимать CHAR* и пихать в FindFirstFile. А уже в процессе пихания оно превратится в LPCSTR.
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
05.10.2016, 20:47  [ТС] 16
Цитата Сообщение от Renji Посмотреть сообщение
Ваша функция должна принимать CHAR* и пихать в FindFirstFile.
Ну так я в нее и пихаю. Или то что я в нее пихаю все же не то?
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
05.10.2016, 21:36 17
Цитата Сообщение от Mr_Sorry Посмотреть сообщение
Ну так я в нее и пихаю. Или то что я в нее пихаю все же не то?
А, пардон, проглючило, показалось что вы пытались в NamesDIrectory и старый путь хранить, и новый, а ошибка вылетала из-за попытки в константный NamesDIrectory писать. В этом случае как раз и надо было бы менять LPCSTR на входе функции на CHAR*. Теперь заметил что новый путь вы в отдельную переменную пишете.
0
0 / 0 / 0
Регистрация: 30.03.2015
Сообщений: 33
05.10.2016, 22:57  [ТС] 18
Цитата Сообщение от Renji Посмотреть сообщение
Теперь заметил что новый путь вы в отдельную переменную пишете.
Да, моя функция полностью заработала. Внес еще одну коррективу для пропуска некоторых моментов. Считает все точь в точь. Спасибо за помощь.
0
05.10.2016, 22:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.10.2016, 22:57
Помогаю со студенческими работами здесь

Найти суммарный размер всех файлов указанного типа на указанном диске
Скрипт, который находит суммарный размер всех файлов указанного типа на указанном диске.

Скрипт, который находит суммарный размер всех файлов указанного типа на указанном диске.
Скрипт, который находит суммарный размер всех файлов указанного типа на указанном диске. Вывод...

Проверка наличия на диске в указанном каталоге перечисленных в списке файлов и вывод имен отсутствующих
Проверка наличия на диске в каталоге, указанном первым параметром КФ файла FNames.txt, содержащего...

Поиск файлов на диске с исключением папок
Такой вопрос: как это реализовать ? Есть рабочий код который нашел на просторах интернета, ищет...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru