Возникла необходимость в пакетной обработке файлов, переименовывание, копирование и т.д. Для этого imho нужно совершить сабж с помощью функций группы FindFile. Так вот, хотел спросить как-бы это сделать пооптимальнее. Желательно по скорости, и чтобы памяти не так много тратилось. Что я знаю: 1) Перечислять все файлы в текущей папке, после того как нашли вложенную папку, занести её номер в массив и перейти в неё. Дальше тоже, пока не нашли последнюю. Затем идем в предидущую, снова перечисляем, а с имеющимся номером пропускаем. Всё вроде просто, но долго. Сложность только в одной папке (n^2+n)/2, а если много вложений, то очень долго. 2) Перечислять все разу и заносить имена папок в массив, потом заходить в первую и тоже заносить в массив и т.д. Быстро, но много нужно памяти. З.Ы. Может попробовать функции Shell, там тоже вроде список файлов создаётся, но хотелось бы узнать, как эти функции по скорости и по памяти?
infern0 Как раз устраивает. Значит я не понял принципа работы FindNextFile. Если я не закрою хендл полученый FindFirstFile, то при возврате в предидущий каталог с тем же хендлом, поиск будет продолжаться далее, а не сначала. Сорри, заблуждался в такой простой вещи.
Больше времени тратится не на обход папок, скорее, а на саму обработку найденых файлов. Я как-то делал приблизитеьно так, скорость вполне устраивала: Код (Text): pushad xor ebx,ebx push ebx NextDir: call Обработка_текущего_каталога call FindFirstFileA, offset SMaska, offset FData mov [FHandle],eax jmp Oblom NextLoop: mov [FHandle],eax loop1: call FindNextFileA, [FHandle], offset FData Oblom: or eax,eax jz PreviousDir cmp byte ptr [FData.cFileName],'.' jz loop1 test [FData.dwFileAttributes],00010000b jz loop1 call SetCurrentDirectoryA, offset FData.cFileName push [FHandle] jmp NextDir PreviousDir: call FindClose, [FHandle] call SetCurrentDirectoryA, offset UP pop eax or eax,eax jnz NextLoop popad up db '..',0 SMaska db '*.*',0
Скорость простого обхода всего дерева каталогов (без обработки даже) занимает значительное время, особенно на больших дисках. Под NT лучше вызывать NtQueryDirectoryFile, это будет чуть быстрее за счёт сокращения цепочки вызовов API (FindFirstFile,FindNextFile проходят несколько других функций и упираются в NtQueryDirectoryFile). Если хочется ещё быстрее, пишем код для работы непосредственно с файловой системой.
Когда-то давно я написал алгоритм обхода каталогов без рекурсии в явном виде и без выделения памяти. 408591482__Find3str.asm
Спасибо всем за информацию. В моём случае необходимо сделать обход сотен тысяч файлов (и более), и записать их имена в файл. По моим тестам вышло, что основные тормоза именно при обходе. Но тут у меня ещё возникли проблемы. При запуске под юзером, программа падает на недоступных ему папках, оно и понятно. Сделал проверку после SetCurrentDirectory и недоступные папки в "Documents and Settings" просто стали пропускаться. Но вот почему-то WINDOWS\system32\spool\PRINTERS устанавливается в текущую, последующий вызов FindFirstFile проваливается, а затем и сама прога падает. Папка PRINTERS также недоступна, и из виндов я в неё зайти не могу.