Pesquisa de arquivos
Autor: Carlão | Publicado: 2006-07-15T17:11:00-05:00

Buscar arquivos num diretório ou subdiretório exige conhecimento de uma coisa simples mas que pode causar problemas: fazer uma função chamar ela mesma. Às vezes a função não mantém registro do status de sua execução e então uma próxima execução não é controlada de maneira correta e pode haver o tal Stack Overflow (a recursividade "infinita").Para pesquisar arquivos em diretórios usa-se as funções FindFirst, FindNext e FindClose.FindFirst - deve ser usada pelo menos uma vez. É a função que inicia o processo de pesquisa, recebendo os parâmetros iniciais e retornando o resultado da pesquisa de acordo com esses parâmetros (que são atribuídos ao registro do tipo TSearchRec, passado como parâmetro a essa função). Se retornar zero, pelo menos um arquivo foi encontrado. function FindFirst(const Path: string; Attr: Integer;var F: TSearchRec): Integer;As máscaras (*) são usadas na variável Path que passada para a função FindFirst. Por exemplo, para que a função retorne somente os arquivos do word da pasta C:\Meus Documentos, os parâmetros seriam:FindFirst('C:\MEUS DOCUMENTOS\*.DOC', faAnyFile, sr)faAnyfile indica qualquer arquivo. Esse segundo parâmetro informa a função que qualquer arquivo pode ser retornado sendo os arquivos divididos nessas categorias:Constante             DescriçãofaReadOnly     arquivos marcados como "somente leitura"faHidden              arquivos ocultosfaSysFile      arquivos do sistemafaVolumeID     arquivos" que representam drives - C, D, A..faDirectory    diretórios (sim, são arquivos)faArchive      arquivos de arquivamento - será isso?faAnyFile      qualquer um dos citadosO resultado de FindFirst é armazenado no terceiro parâmetro, nesse caso é a variável sr. Na próxima função eu explico o que existe nesse parâmetro.FindNext - É usada até que retorne um código de erro, que indica que a função não encontrou mais arquivos. As informações sobre cada arquivo são passadas a essa função pelo parâmetro do tipo TSearchRec usado na função FindFirst.TSearchRec = recordTime: Integer;Size: Integer;Attr: Integer;Name: TFileName;ExcludeAttr: Integer;FindHandle: THandle;FindData: TWin32FindData;end;Abaixo,  o código fonte:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants,Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, FileCtrl, ExtCtrls;typeTForm1 = class(TForm)ListBox1: TListBox;Panel1: TPanel;Button1: TButton;Edit1: TEdit;Label1: TLabel;DirectoryListBox1: TDirectoryListBox;CheckBox1: TCheckBox;DriveComboBox1: TDriveComboBox;procedure Button1Click(Sender: TObject);private{ Private declarations }public{ Public declarations }StartTime: Cardinal;Recursive: Integer;procedure FindFiles(const sDirectory: string;const SearchSubfolders: boolean = true);end;varForm1: TForm1;implementation{$R *.dfm}procedure TForm1.FindFiles(const sDirectory: string;const SearchSubfolders: boolean = true);varsr: TSearchRec;beginif DirectoryExists(sDirectory) thentryif Recursive <= 0 thenbeginStartTime:= GetTickCount;Recursive:= 0;ListBox1.Clear;ListBox1.Items.Add('Procurando por '+edit1.Text);end;if SysUtils.FindFirst(sDirectory+'\*.*',     faAnyFile, sr) = 0 thenbeginrepeatcase sr.Attr offaDirectory:             if SearchSubfolders then             if (Sr.Name <> '.') and                (Sr.Name <> '..') then             begin                 Inc(Recursive);                 FindFiles(sDirectory +'\'+ sr.Name);             end;else    if Pos(AnsiUpperCase(Edit1.Text),    AnsiUpperCase(sr.Name)) <> 0 then    ListBox1.Items.Add(sDirectory + '\' + sr.Name);end;until SysUtils.FindNext(sr) <> 0;end;finallySysUtils.FindClose(sr);Dec(Recursive);if Recursive < 0 thenbeginListBox1.Items.Add('Terminado em ' +IntToStr(GetTickCount - StartTime)+'ms.');ListBox1.ItemIndex:= ListBox1.Count-1;end;end;end;procedure TForm1.Button1Click(Sender: TObject);beginFindFiles( DirectoryListBox1.Directory, CheckBox1.Checked);end;end.Código fonte transformado em HTML por http://tohtml.com/pascal/Gostou? Sugere alguma coisa? Comente!