Обход дерева каталогов

Тема в разделе "WASM.A&O", создана пользователем Booster, 20 апр 2005.

  1. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Возникла необходимость в пакетной обработке файлов, переименовывание, копирование и т.д. Для этого imho нужно совершить сабж с помощью функций группы FindFile. Так вот, хотел спросить как-бы это сделать пооптимальнее. Желательно по скорости, и чтобы памяти не так много тратилось. Что я знаю:



    1) Перечислять все файлы в текущей папке, после того как нашли вложенную папку, занести её номер в массив и перейти в неё. Дальше тоже, пока не нашли последнюю. Затем идем в предидущую, снова перечисляем, а с имеющимся номером пропускаем.

    Всё вроде просто, но долго. Сложность только в одной папке (n^2+n)/2, а если много вложений, то очень долго.



    2) Перечислять все разу и заносить имена папок в массив, потом заходить в первую и тоже заносить в массив и т.д.

    Быстро, но много нужно памяти.



    З.Ы. Может попробовать функции Shell, там тоже вроде список файлов создаётся, но хотелось бы узнать, как эти функции по скорости и по памяти?
     
  2. infern0

    infern0 New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2003
    Сообщения:
    811
    Адрес:
    Russia
    обычная рекурсия чем не устравивает ?
     
  3. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    infern0





    Как раз устраивает. Значит я не понял принципа работы FindNextFile. Если я не закрою хендл полученый FindFirstFile, то при возврате в предидущий каталог с тем же хендлом, поиск будет продолжаться далее, а не сначала. Сорри, заблуждался в такой простой вещи.
     
  4. Mad__C

    Mad__C New Member

    Публикаций:
    0
    Регистрация:
    9 сен 2004
    Сообщения:
    13
    Больше времени тратится не на обход папок, скорее, а на саму обработку найденых файлов.

    Я как-то делал приблизитеьно так, скорость вполне устраивала:


    Код (Text):
    1.  
    2.              pushad
    3.              xor   ebx,ebx
    4.              push  ebx
    5. NextDir:
    6.              call  Обработка_текущего_каталога
    7.              call  FindFirstFileA, offset SMaska, offset FData
    8.              mov   [FHandle],eax
    9.              jmp   Oblom
    10. NextLoop:
    11.              mov   [FHandle],eax
    12. loop1:
    13.              call  FindNextFileA, [FHandle], offset FData
    14. Oblom:
    15.              or    eax,eax
    16.              jz    PreviousDir
    17.              cmp   byte ptr [FData.cFileName],'.'
    18.              jz    loop1
    19.              test  [FData.dwFileAttributes],00010000b
    20.              jz    loop1
    21.  
    22.              call  SetCurrentDirectoryA, offset FData.cFileName
    23.              push  [FHandle]
    24.              jmp   NextDir
    25. PreviousDir:
    26.              call  FindClose, [FHandle]
    27.              call  SetCurrentDirectoryA, offset UP
    28.              pop   eax
    29.              or    eax,eax
    30.              jnz   NextLoop
    31.              popad
    32. up           db    '..',0
    33. SMaska       db    '*.*',0
    34.  
     
  5. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Скорость простого обхода всего дерева каталогов (без обработки даже) занимает значительное время, особенно на больших дисках.



    Под NT лучше вызывать NtQueryDirectoryFile, это будет чуть быстрее за счёт сокращения цепочки вызовов API (FindFirstFile,FindNextFile проходят несколько других функций и упираются в NtQueryDirectoryFile).



    Если хочется ещё быстрее, пишем код для работы непосредственно с файловой системой.
     
  6. Avalonec

    Avalonec New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    111
    Адрес:
    Тула
    Под винду работа с файлами кешируется, так что во второй раз будет уже значительно быстрее.
     
  7. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Когда-то давно я написал алгоритм обхода каталогов без рекурсии в явном виде и без выделения памяти.

    [​IMG] 408591482__Find3str.asm
     
  8. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Спасибо всем за информацию. В моём случае необходимо сделать обход сотен тысяч файлов (и более), и записать их имена в файл. По моим тестам вышло, что основные тормоза именно при обходе.

    Но тут у меня ещё возникли проблемы. При запуске под юзером, программа падает на недоступных ему папках, оно и понятно. Сделал проверку после SetCurrentDirectory и недоступные папки в "Documents and Settings" просто стали пропускаться. Но вот почему-то WINDOWS\system32\spool\PRINTERS устанавливается в текущую, последующий вызов FindFirstFile проваливается, а затем и сама прога падает. Папка PRINTERS также недоступна, и из виндов я в неё зайти не могу.