Конференция "Начинающим" » Поиск файлов [D7, WinXP]
 
  • User (23.06.08 18:52) [0]
    Возвращаясь к 'избитой' теме ... Поиск файлов по схеме, предложенной в FAQ, работает хорошо только для случаев:
    1 - нужно найти ВСЕ файлы;
    2 - нужно найти файлы определенного (одного) типа при условии, что хотябы один такой файл находится в искомом (начальном) каталоге - условие
     if (FindFirst(StartDir+Mask, faAnyFile, SearchRec) = 0) then ...


    не выполняется, если файл не найден  ...
    В остальных случаях (, у меня, во всяком случае) не работает.
    То есть, путей решения для решения такой задачи, как поиск файлов определенных расширений (предположим, '*.txt; *.rtf, *.doc') в указанном каталоге (с вложенными папками, и не обязательно содержащий файлы - например, корневой) я не нашел ...
    Буду признателен за помощь, может кому еще сгодиться ...


  • clickmaker © (23.06.08 18:55) [1]
    > То есть, путей решения для решения такой задачи, как поиск
    > файлов определенных расширений

    а в чем проблема? Рекурсию организовать и вызвать MatchesMask()?
  • User (23.06.08 19:00) [2]
    ... да, ещё ... перехвалил FAQ - для маски, отличной от '*.*' поиск осуществляется только в искомом каталоге ...
  • User (23.06.08 19:09) [3]
    2 clickmaker
    MatchesMask проверяет, соответствует ли файл FileName маске, определенной в параметре Mask.

    ...
    не знаю каким боком ее впихнуть, да и зачем? - маски я могу и самостоятельно менять, и можно, наверное наваять следующее:

     if (FindFirst(StartDir+Mask1, faAnyFile, SearchRec) = 0) or
       (FindFirst(StartDir+Mask2, faAnyFile, SearchRec) = 0) or ...
         (FindFirst(StartDir+MaskN, faAnyFile, SearchRec) = 0) then begin ...


    Но, как оказалось, поиск не хочет проходить во вложенных папках ...
  • clickmaker © (23.06.08 19:12) [4]
    > поиск не хочет проходить во вложенных папках ...

    а с какой радости он должен хотеть?
  • Anatoly Podgoretsky © (23.06.08 19:16) [5]
    Не понятно на какой FAQ ты ссылаешься, они разные бывают, хорошие и так себе.
  • Anatoly Podgoretsky © (23.06.08 19:17) [6]

    > для маски, отличной от '*.*' поиск осуществляется только
    > в искомом каталоге ...

    Неправда
  • Anatoly Podgoretsky © (23.06.08 19:20) [7]

    > а с какой радости он должен хотеть?

    Он всегда хочет, если это хотение подтверждено маской и правами, но автор к сожалению совсем не понимает принципов работы ДОС и ее наследников.
  • User (23.06.08 19:27) [8]
    2 Anatoly Podgoretsky
    www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=1015254946&n=19

    > Неправда

    ... таки да, вот кусок:

     ...
     GetDir(0, cDir); // получить имя текущего каталога
     if cDir[length(cDir)] <> '\' then cDir := cDir+'\';
     ListBox1.Items.Clear;
     ScanDir(cDir, '*.pas', ListBox1.Items);
     ...


    , функция из FAQ, без изменений - при '' (по умолчанию '*.*') рубит, при других комбинациях - ищет только в указанном каталоге ...
  • User (23.06.08 19:33) [9]

    > но автор к сожалению совсем не понимает принципов работы
    > ДОС и ее наследников.

    - оставим в стороне мои понимания ДОС и, тем более, наследников - если это ко мне... взяв готовый кусок и применив к своей задаче, я не получил ожидаемого результата :-(
    На счет варианта в [3] - поиск ведется только по первой маске - к слову ...
  • Anatoly Podgoretsky © (23.06.08 19:47) [10]
    А тут не наблюдается вторая маска, поэтому утверждение "поиск ведется только по первой маске" не имеет смысла.  В приведеном коде нет никаких ошибок, все работает в соответствии с логикой, будут искаться файлы с маской *.pas и ничего более.
  • Anatoly Podgoretsky © (23.06.08 19:49) [11]
    Без понимания ДОС у тебя ничего не получится, ну разве кто то даст тебе готовый код, но можно и оставить это в стороне, как то все равно, особенно раз ты сам сопротивляешься.
  • User (23.06.08 21:22) [12]
    ... 'пересел' с Delphi 2006 на D7 - те же ...
    имею папка 'Borland Delphi Projects', содержащую около десятка вложенных папок (те, в свою очередь, также имеют по несколько вложеных папок); в каждой папке, как минимум - один файл '*.pas'...
    запускаю в пошаговом режиме, указав стартовой указанную папку, - прохожу

    if (SearchRec.Attr and faDirectory) <> faDirectory
    then List.Add(StartDir + SearchRec.Name)


    несколько раз (кол-во пас-ов минус один), а в

      else if (SearchRec.Name <> '..') and (SearchRec.Name <> '.')
        then begin


    никак ...
    При '*.*' проходит все участки, тоесть (SearchRec.Attr and faDirectory) <> faDirectory при расширении, отличном от * почему-то (?) не работает.

    > А тут не наблюдается вторая маска, поэтому утверждение "поиск
    > ведется только по первой маске" не имеет смысла.

    - относится к

    > ..., и можно, наверное наваять следующее...



    > Без понимания ДОС у тебя ничего не получится, ну разве кто
    > то даст тебе готовый код, но можно и оставить это в стороне,
    >  как то все равно, особенно раз ты сам сопротивляешься

    Да понимаю я ДОСе в достаточном объёме ...
  • Anatoly Podgoretsky © (23.06.08 21:34) [13]
    Ни фига ты не понимаешь ДОС, совсем не понимаешь, отсюда и твои проблемы. По другому - ты в логике не разбираешься. Все работает в соответствии с твоей логикой, сказано обрабатывать маску *.pas, а папком в таком формате наверно нет.
    Если и это http://www.podgoretsky.com/ftp/Docs/Delphi/FAQ/ru.delphi.html#N157 тебе не поможет, то я не знаю, что с тобой делать, разве в лес послать.
  • Тын-Дын © (23.06.08 21:37) [14]

    > User   (23.06.08 21:22) [12]


    Направильно пользуешься FindFirst/FindNext/FindClose.
    Держи пример, адаптированный под твою задачу.

    function GetFiles(const aPath: String;MasksStr: String;aListFile: TStrings): Boolean;
    var
     SR: TSearchRec;
     tPath: String;
     LMask: TStringList;
     i: Integer;
    begin
     LMask := TStringList.Create;
     try
    {$WARN SYMBOL_PLATFORM OFF}
       tPath := IncludeTrailingBackSlash(aPath);
    {$WARN SYMBOL_PLATFORM ON}
       Result := True;
       try
         LMask.Delimiter := ';';
         LMask.DelimitedText := MasksSTr;
         if FindFirst(tPath+'*.*',faAnyFile,SR)=0 then
         begin
           try
             repeat
               if (SR.Name='.') or (SR.Name='..') then Continue;
               if (SR.Attr and faDirectory)<>faDirectory then
               begin
                 for i :=0 to LMask.Count-1 do
                 begin
                   if MatchesMask(SR.Name,LMask[i]) then
                   begin
                     aListFile.Add(tPath+SR.Name);
                     Break;
                   end;
                 end;
               end
               else GetFiles(tPath+SR.Name,MasksStr,aListFile);
             until FindNext(SR)<>0;
           finally
             Sysutils.FindClose(SR);
           end;
         end;
       except
         Result := False;
       end;
     finally
       LMask.Free;
     end;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
     GetFiles('c:\','*.pas;*.dpr',Memo1.Lines);
    end;

  • User (23.06.08 21:52) [15]
    2 Тын-Дын оно!
    2 Anatoly Podgoretsky

    > Направильно пользуешься FindFirst/FindNext/FindClose.

    Причем тут знание ДОСа?, если FindFirst/FindNext устанавливает атрибуты по 'первому случаю'  - директория в случае '*.*' найдется (SearchRec.Attr = faDirectory) , но врядли найдется директория '*.pas', или аналогичная. По приколу попробывал - создал папку 'Papka.pas', впихнул туда несколько пас-ов - нашел (в программе) и эту папку, и файлы в нем, и только!
  • Anatoly Podgoretsky © (23.06.08 22:04) [16]
    > User  (23.06.2008 21:52:15)  [15]

    Нет разницы между папкой и файлом, кроме аттрибута.
    Маска не позволяет тебе войти ни в одну папку кроме *.pas в соответствии с правилами работы файловых систем ДОС и его наследников.
    Логику работы файловых систем ты не понимаешь.
  • Юрий Зотов © (23.06.08 22:06) [17]
    > User   (23.06.08 21:52) [15]

    > создал папку 'Papka.pas', впихнул туда несколько пас-ов - нашел (в
    > программе) и эту папку, и файлы в нем, и только!

    И что тут странного? Что должен был найти, то и нашел. В чем проблема-то?

    В справке есть и подробное описание, и пример - почему бы не заглянуть туда?
  • User (23.06.08 22:16) [18]

    > Нет разницы между папкой и файлом, кроме аттрибута.
    > Маска не позволяет тебе войти ни в одну папку кроме *.pas
    > в соответствии с правилами работы файловых систем ДОС и
    > его наследников.
    - а я о чем, см:

    > функция из FAQ, без изменений - при '' (по умолчанию '*.
    > *') рубит, при других комбинациях - ищет только в указанном
    > каталоге

    , а Вы

    > Неправда, неправда

    Вопрос же был по FAQ, значит там ошибка!

    >В справке есть и подробное описание, и пример -
    >почему бы не заглянуть туда?

    ... можно, заглядывал, но на счет атрибутов 'осенило' только после трассировки ...
    Всем спасибо за внимание! Код Тын-Дына можно переносить в FAQ.
    Если нет никаких замечаний, думаю тему можно закрывать. Благодарю.
  • Anatoly Podgoretsky © (23.06.08 22:26) [19]
    > User  (23.06.2008 22:16:18)  [18]

    > Вопрос же был по FAQ, значит там ошибка!

    Что бы это утверждать нужно видеть текст статьи, но я думаю, что ты ее просто не понял, выдал желаемое за действительное.
    Хотя сказать точно можно будет только после приведения описания/текста статьи в FAQ
  • User (23.06.08 22:35) [20]

    > 2 Anatoly Podgoretsky
    > www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=1015254946&n=19
    >
    > = Как получить список файлов со всеми подкаталогами
    > ...
    > Пример вызова, параметры
    > 1. имя папки
    > 2. маска, по умолчанию *.*
    > 3. хранилище для резульатат,
    >   любой наследник от TString, например TStringList
    >
    > procedure TForm1.Button1Click(Sender: TObject);
    > begin
    >   ListBox1.Items.Clear;  
    >   ScanDir('c:','',ListBox1.Items);
    >   Label1.Caption := IntToStr (ListBox1.Items.Count);
    > end;
    >
    > С уважением
    > Анатолий Подгорецкий  
    ... исчерпывающе ...
  • Anatoly Podgoretsky © (23.06.08 22:48) [21]
    > User  (23.06.2008 22:35:20)  [20]

    Ну все правильно, а какое возражение есть, если же указаное не устраивает, то смотри FAQ из ФИДО на моем сайте, там есть поиск независимый от масок.
  • Anatoly Podgoretsky © (23.06.08 22:50) [22]
  • User (23.06.08 23:02) [23]
    за ссылку спасибо, буду посматривать ...
    ... пример, действительно рабочий, но для моего случая предпочтительнее вариант Тын-Дына, т.к. можно одновременно искать несколько типов файлов ...
  • Тын-Дын © (24.06.08 10:15) [24]

    > User   (23.06.08 23:02) [23]
    > за ссылку спасибо, буду посматривать ...
    > ... пример, действительно рабочий, но для моего случая предпочтительнее
    > вариант Тын-Дына, т.к. можно одновременно искать несколько
    > типов файлов ...


    Это пример, написанный "на коленках". Оптимизировать ещё нужно.
 
Конференция "Начинающим" » Поиск файлов [D7, WinXP]
Есть новые Нет новых   [134435   +33][b:0][p:0.003]