<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=39461&amp;view=findpost&amp;p=255714</guid>
        <pubDate>Mon, 01 Dec 2003 18:22:14 +0000</pubDate>
        <title>Найти все файлы (директории) по маске</title>
        <link>https://forum.sources.ru/index.php?showtopic=39461&amp;view=findpost&amp;p=255714</link>
        <description><![CDATA[Song: Чтобы найти файл(файлы), директорию(ии) мы можем воспользоваться структурой TSearchRec:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type TSearchRec = record</div><div class="code_line">&nbsp;           Time: Integer;</div><div class="code_line">&nbsp;           Size: Integer;</div><div class="code_line">&nbsp;           Attr: Integer;</div><div class="code_line">&nbsp;           Name: TFileName;</div><div class="code_line">&nbsp;           ExcludeAttr: Integer;</div><div class="code_line">&nbsp;           Mode: mode_t;</div><div class="code_line">&nbsp;           FindHandle: Pointer;</div><div class="code_line">&nbsp;           PathOnly: array [0..4096] of char;</div><div class="code_line">&nbsp;           Pattern: array [0..256] of char;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">On Windows:</div><div class="code_line">&nbsp;</div><div class="code_line">type </div><div class="code_line">TSearchRec = record</div><div class="code_line">&nbsp;           Time: Integer;</div><div class="code_line">&nbsp;           Size: Integer;</div><div class="code_line">&nbsp;           Attr: Integer;</div><div class="code_line">&nbsp;           Name: TFileName;</div><div class="code_line">&nbsp;           ExcludeAttr: Integer;</div><div class="code_line">&nbsp;           FindHandle: THandle;</div><div class="code_line">&nbsp;           FindData: TWin32FindData;</div><div class="code_line">end;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Для поиска мы можем воспользоваться процедурами FindFirst/FindNext/FindClose<br>
<br>
FindFirst - ищет первый файл, отвечающий критериям поиска<br>
FindNext - ищет следующий(ие) файл(ы)<br>
FindClose - закрывает поиск и освобождает занятые ресурсы при поиске.<br>
<br>
FindFirst/FindNext возвращают в случае успеха 0. FindClose необходимо делать, если хотя бы FindFirst вернула успешный код завершения т.е. 0<br>
Найденный(ые) файл(ы) возвращаются в вышеупомянутой структуре TSearchRec. т.е., например, TSearchRec.Name будет содержать имя найденного файла.<br>
<br>
Синтаксис:<br>
function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;<br>
Path - путь поиска<br>
F - переменная с типом TSearchRec<br>
<br>
В FindFirst мы можем указать маску файлов. Например искать все файлы MS Word - &#39;*.doc&#39;. Для поиска файлов по аттрибутам мы можем воспользоваться перемменой Attr:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Constant      Value      Description</div><div class="code_line">faReadOnly      {text}000001      Read-only files</div><div class="code_line">faHidden      {text}000002      Hidden files</div><div class="code_line">faSysFile      {text}000004      System files</div><div class="code_line">faVolumeID      {text}000008      Volume ID files</div><div class="code_line">faDirectory      {text}000010      Directory files</div><div class="code_line">faArchive      {text}000020      Archive files</div><div class="code_line">faAnyFile      {text}00003F      Any file</div></ol></div></div></div></div><br>
<br>
Все аттрибуты могут легко комбинировать плюсом и взаимоисключаться минусом.<br>
Например найти найти все системные и скрытые файлы: faHidden+faSysFile.<br>
<br>
И в заключение небольшой пример.<br>
Найдём все файлы в директории C:&#092;Temp и добавим их в TMemo<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Procedure FindAll(Path:String; Memo:TMemo);</div><div class="code_line">Var SearchRec:TSearcRec;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;IF FindFirst(Path,faAnyFile-faDirectory,SearchRec)=0 then</div><div class="code_line">&nbsp; try</div><div class="code_line">&nbsp;  Memo.Lines.Add(SearcRec.Name);</div><div class="code_line">&nbsp;  While FindNext(SearchRec)=0 Do Memo.Lines.Add(SearchRec.Name);</div><div class="code_line">&nbsp; finally</div><div class="code_line">&nbsp;  FindClose(SearchRec);</div><div class="code_line">&nbsp; end;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure TForm1.Button1Click(Sender:TObject);</div><div class="code_line">Begin</div><div class="code_line">&nbsp;Memo1.Lines.Clear;</div><div class="code_line">&nbsp;FindAll(&#39;C:\Utils\*.*&#39;,Memo1);</div><div class="code_line">End;</div></ol></div></div></div></div><br>
<br>
Заметьте, что в аттрибутах я использовал минус, хотя мне надо было найти все файлы. Дело в том, что по спецификации файловой системы Dos и Windows в каждом каталоге кроме корневого есть элементы, которые называются &quot;.&quot; и &quot;..&quot; Первый из них показывает корневую директорию, второй - наддиректорию. Они имеют аттрибут faDirectory. Поэтому, чтобы в нашем примере они не попали в TMemo, мы их взаимоисключаем.<br>
Удачи.<br>
<br>
Указанный пример будет работать только в пределах одной директории. Но очень часто нам надо перебрать много директорий и/или файлов, по всему жёсктому диску например. Для этого нам надо использовать рекурсию. Рекурсия (рекурсивный вызов) - это вызов процедуры/функции из неё самой. При программировании рекурсии, надо быть осторожным т.к. случайное недопонимание элементов рекурсивного алгоритма может привести к бесконечной рекурсии т.е. постоянному зацикливанию. Это приведёт к тому, что в программе очень быстро кончится стёк, выполнение парализуется и закончится фатальной ошибкой. В следующем примере показано как использовать рекурсивный вызов функций FindFirst/FindNext, чтобы перебрать все файлы на диске. Для примера показан способ получения всех файлов и директорий на диске:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Procedure ScanDir(StartDir: String; Mask:string; List:TStrings);</div><div class="code_line">{ Процедура выводит список директории в список List, начиная с директории, указанной в StartDir. Mask - маска для получения файлов </div><div class="code_line">Источник delphi.mastak.ru</div><div class="code_line">© А. Подгорецкий }</div><div class="code_line">Var SearchRec : TSearchRec;</div><div class="code_line">Begin</div><div class="code_line">&nbsp; IF Mask =&#39;&#39; then Mask:= &#39;*.*&#39;;</div><div class="code_line">&nbsp; IF StartDir[Length(StartDir)] &#60;&#62; &#39;\&#39; then StartDir := StartDir + &#39;\&#39;;</div><div class="code_line">  IF FindFirst(StartDir+Mask, faAnyFile, SearchRec) = 0 then</div><div class="code_line">&nbsp;   Begin</div><div class="code_line">&nbsp;    Repeat</div><div class="code_line">&nbsp;       { Чтобы выполнение &quot;не подвисало&quot; }</div><div class="code_line">&nbsp;     Application.ProcessMessages;</div><div class="code_line">&nbsp;     IF (SearchRec.Attr and faDirectory) &#60;&#62; faDirectory then </div><div class="code_line">&nbsp;        List.Add(StartDir + SearchRec.Name) else </div><div class="code_line">&nbsp;         IF (SearchRec.Name &#60;&#62; &#39;..&#39;) and (SearchRec.Name &#60;&#62; &#39;.&#39;) then</div><div class="code_line">&nbsp;       Begin</div><div class="code_line">&nbsp;         List.Add(StartDir + SearchRec.Name + &#39;\&#39;);</div><div class="code_line">&nbsp;           { Рекурсивный вызов }</div><div class="code_line">&nbsp;         ScanDir(StartDir + SearchRec.Name + &#39;\&#39;,Mask,List);</div><div class="code_line">&nbsp;       End;</div><div class="code_line">&nbsp;    Until FindNext(SearchRec) &#60;&#62; 0;</div><div class="code_line">&nbsp;    FindClose(SearchRec);</div><div class="code_line">&nbsp;  End; {IF}</div><div class="code_line">end;</div></ol></div></div></div></div><br>
<br>
Пример вызова:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure TForm1.Button1Click(Sender: TObject);</div><div class="code_line">{ Пример вызова</div><div class="code_line">Источник delphi.mastak.ru }</div><div class="code_line">begin</div><div class="code_line">&nbsp; ListBox1.Items.Clear;</div><div class="code_line">&nbsp; ScanDir(&#39;c:&#39;,&#39;&#39;,ListBox1.Items);</div><div class="code_line">&nbsp; Label1.Caption := IntToStr(ListBox1.Items.Count);</div><div class="code_line">end;</div></ol></div></div></div></div>]]></description>
        <author>Song</author>
        <category>Работа с файлами, форматы файлов и данных</category>
      </item>
	
      </channel>
      </rss>
	