Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/34: Рейтинг темы: голосов - 34, средняя оценка - 4.65
12 / 12 / 4
Регистрация: 04.08.2010
Сообщений: 80

Рекурсивный обход (FindFirstFile, FindNextFile)

27.01.2012, 05:37. Показов 6347. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Перед мной стоит задача выполнить поиск и некоторую работу со всеми файлами в определенном каталоге, количества директорий и файлов не фиксированное(файлов >60000).
Я решили эту задачу с помощью рекурсивных вызовов FindFirstFile,FindNextFile.
Собственно вопрос: возможно ли ускорить этот процесс?Избавиться от рекурсии?

Заранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.01.2012, 05:37
Ответы с готовыми решениями:

FindFirstFile и FindNextFile рекурсивный поиск файла
Как безопасно (без всевозможных переполнений и высвобождением ресурсов) реализовать рекурсивный поиск файла на одном из разделов диска? Или...

FindFirstFile, FindNextFile и setLocale
Пытался пройти по файлам в каталоге, как в примере на MSDN. Написал такой код #include <windows.h> #include <iostream> ...

FindNextFile,FindFirstFile,FindClose
#include <windows.h> #include <iostream> #include<tchar.h> using namespace std; //strcpy, strcat //_tcscpy,_tcscat int...

5
Исследователь
 Аватар для GrayWolf
318 / 317 / 24
Регистрация: 06.04.2011
Сообщений: 872
29.01.2012, 07:36
Думаю, что нет. Теоретически можно использовать обычный цикл, но перед нами стоит задача не только "войти" в каталог, но и "выйти" из него, что грозит лишним расходом памяти для запоминания тех каталогов (родительских), которые мы уже посетили. И, следовательно, размер кода значительно увеличится.
А чем вас не устраивает рекурсия? В принципе, скорость ее работы ограничивается только квантами выделенного процессорного времени и скоростью работы винчестера. А они сейчас и так высоки.
0
12 / 12 / 4
Регистрация: 04.08.2010
Сообщений: 80
29.01.2012, 18:37  [ТС]
Количество вызовов функции велико,до десятка тысяч раз-много ест ресурсов.А если к этому прибавить еще некоторые операции над этим файлами и работу с БД, то выполнение программы затягивается на часов 6-8 для количества файлов >60 000.Хотелось бы ускорить этот процесс, борьба с рекурсией как одно из направлений.Да,плюс ко всему, человеческое любопытство=)
0
0 / 0 / 0
Регистрация: 15.10.2013
Сообщений: 2
14.01.2015, 12:24
Я тут сделал без рекурсии. В виде стёка HANDLE поисков, всё в 1 цикле. Пришлось правда хорошо подумать и делать класс. Теоретически должен работать быстрее, т.к. нет вызовов функций и передачи параметров. Но операции с файлами сами по себе медленные.
Для больших объёмов нужно индексирование конечно, возможно ручное делать...

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
    class FindFiles{ //Рекурсивный поиск файлов.
    protected:
        vector<HANDLE> vSearchs; //текущий уровень поиска в дереве папок
        wstring szTempl;
    public:
        wstring szCurPath; //путь до текущего файла 
        WIN32_FIND_DATAW Info; //полученные данные о файле.
        FindFiles(const wstring& szPatch); //указание пути поиска (без последнего разделителя: "C:/Docs")
        ~FindFiles();
        bool Next(); //Найти следующий файла, заполнить Info и szCurPath. Если возвращает 0 поиск закончен.
    };
 
    FindFiles::FindFiles(const wstring& szPatch){
        szTempl = L"*.*"; //шаблон, чтобы находить и папки
        vSearchs.push_back(0);
        szCurPath = szPatch;
    }
    FindFiles::~FindFiles(){
        for (vector<HANDLE>::iterator i = vSearchs.begin(); i != vSearchs.end(); ++i)
            if (*i) FindClose(*i);
    }
    bool FindFiles::Next(){
        while (1){
            if (vSearchs.back() == 0){ //проводим первый поиск
                if (szCurPath == L"") return 0;
                vSearchs.back() = FindFirstFileW( (szCurPath+L"/"+szTempl).c_str(), &Info );
                if (vSearchs.back() == INVALID_HANDLE_VALUE) return 0;
            }else if ( !FindNextFileW(vSearchs.back(), &Info) ){ //или последующий
                if (vSearchs.size() < 2) return 0; //не найдено в главной папке - конец поиска
                FindClose( vSearchs.back() ); //не найденно в подпапке продолжаем поиск в родителе
                vSearchs.pop_back();
                szCurPath = szCurPath.substr(0, szCurPath.rfind(L'/'));
                continue;
            }
            if (wcscmp(Info.cFileName, L".") == 0 || wcscmp(Info.cFileName, L"..") == 0) continue; //пропуск ссылок на себя и родителя
            if (Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ //нашли папку, заходим в неё
                szCurPath += L"/"+wstring(Info.cFileName);
                vSearchs.push_back(0);
                continue;
            }
            return 1; //найден файл (данные были записаны сразу)
        }
        return 0;
    }
Пример использования:
C++
1
2
3
4
5
6
7
    FindFiles findFile(L"C:\Docs");
    while (findFile.Next()){
        wstring szExt = GetFileExtension(findFile.Info.cFileName); //только doc
        if (szExt == L"doc"){
            ReadFile( findFile.szCurPath+L"/"+WStr(findFile.Info.cFileName) ) ;
        }
    }
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
14.01.2015, 12:44
Цитата Сообщение от RomanLesNik Посмотреть сообщение
А если к этому прибавить еще некоторые операции над этим файлами и работу с БД, то выполнение программы затягивается на часов 6-8 для количества файлов >60 000.
Для начала сделайте точные замеры: сколько процентов этого времени
уходит на поиск файлов, а сколько на их обработку и работу с БД.
Файловый I/O невозможно ускорить, как не пытайся, а вот по второму пункту
можно сделать какую-то оптимизацию, например вынести в отдельный поток.
0
12 / 12 / 4
Регистрация: 04.08.2010
Сообщений: 80
19.01.2015, 20:36  [ТС]
Спасибо за ответ спустя 3 года, честно говоря я и забыл что такой вопрос то задавал. Задача была решена позже, в другом проекте, на другом языке. Вкратце: писал на яве, избавился от рекурсии складывая данные в список + некоторые явовские извращения, что касается БД, то использовалась sqlite, с отключенным журналированием, все данные вставлялись в пару транзакций итого сканирование всех файлов на диске(~160 000),сплитинг пути на части и вставка в базу выполнялсь около 15-20 секунд
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
19.01.2015, 20:36
Помогаю со студенческими работами здесь

Поиск папок с помощью FindFirstFile\FindNextFile
Как найти только папки?

WIN32 FindFirstFile и FindNextFile возвращают некорректное время
Здравствуйте. При листинге каталога Windows функциями FindFirstFile и FindNextFile таким образом: bool ListLocalDirectory(HANDLE...

FindNextFile в do {} while()
Здравствуйте. Хочу перебрать в цикле все файлы и папки в папке. Использую такой код: GetCurrentDirectory(9999, Buffer); //...

FindNextFile
#include &lt;Windows.h&gt; #include &lt;iostream&gt; int main(int argc, TCHAR *argv) { WIN32_FIND_DATA dt; HANDLE handle; handle =...

Функция FindFirstFile
Нужно получить размер файла с помощью функции FindFirstFile.Но параметры nFileSizeHigh и nFileSizeLow хранятся в неудобном формате....


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
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 - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru