Russian Qt Forum

Программирование => Алгоритмы => Тема начата: ti0 от Май 15, 2016, 18:10



Название: Запомнить глубину рекурсии
Отправлено: ti0 от Май 15, 2016, 18:10
Есть задача сканировать файловую систему, при этом сканирование может длится достаточно долго. Программа может закрываться, и нужно, что бы когда программа будет вновь запущена, сканирование продолжилось с прерванного места. Есть у кого идеи, как организовать рекурсию?


Название: Re: Запомнить глубину рекурсии
Отправлено: qate от Май 16, 2016, 10:31
а если сначала создать список сканируемых файлов, который отработает быстро
а затем по нему идти, обрабатывать файл и исключать его из созданного списка ?
заодно и прогресс бар будет


Название: Re: Запомнить глубину рекурсии
Отправлено: navrocky от Май 16, 2016, 17:53
Можно запомнить индексы в каждой вложенной ветке и потом стартовать с указанного индекса. Но нет гарантии, что между запусками физический список файлов не изменится.


Название: Re: Запомнить глубину рекурсии
Отправлено: Отражение луны от Май 16, 2016, 22:19
1. Сортируй папки по времени изменения, двигайся от меньшего к большему.
2. Реализуй в рекурсивной функции парсинг "/", т.е. если ты вызываешь функцию с "/dir/subdir1", чтобы она сразу вызывала себя же с "/subdir1", а сама оставалась в состоянии поиска по "/dir" и продолжала поиск дальше когда будет совершен выход из subdir1. Естественно, в таких случаях про получении списка директорий/файлов тебе нужно находить нужную позицию и пропустить те, которые ей предшествуют. Тогда ты легко восстановишь состояние поиска просто передав в функцию аргументы вида ("/path/to/base", "/dir/subdir1/subdir2").
3. Как уже ясно из 2 пункта - 1 параметр - изначальный путь поиска, 2 - относительный, т.е. в случае сканирования с нуля он будет равен "", а в случае сохраненного состояния - относительному пути, до которого дошел твой поиск.
4. Естественно в момент завершения ты сохраняешь оба пути а потом восстанавливаешь.
5. За счет сортировки по времени если файлы и поменяются за время, которое приложение не работало - все измененные папки будут просканированы заново. Возможно, что при таком раскладе некоторые папки будут пересканированы дважды просто потому, что кто-то изменил всего лишь 1 файл где-то далеко внутри пути. Если эти изменения не важны и их можно игнорировать - просто сортируй по алфавиту. В этом случае есть риск пропустить часть данных. Например, если у тебя сканирование закончится на "h..", то если создать папку "b.." и запустить поиск заново - она в итоге просканирована не будет.

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

Но лучше сделать так, как описал этот человек:
а если сначала создать список сканируемых файлов, который отработает быстро
а затем по нему идти, обрабатывать файл и исключать его из созданного списка ?
заодно и прогресс бар будет

// upd

Sumimasen, кажись с путями и сортировкой по времени - это я наврал, и из-за этого будут пропуски. Пути можешь использовать только в случае сортировки по алфавиту (пропуски будут только по новым файлам). В случае с сортировкой по времени тебе нужно в относительном пути использовать timestampы. Тогда наверное будет более-менее нормально работать. И то не факт что я что-то не упустил.


Название: Re: Запомнить глубину рекурсии
Отправлено: Igors от Май 17, 2016, 10:23
Присоединяюсь к первому ответу - рекурсию следует использовать только для получения списка. Возможно список будет большим и придется его упаковать, напр хранить эл-т в виде "ID родителя + имя файла/папки"

"А вдруг что-то изменилось" - это уже другая задача, более сложная