sábado, julho 15, 2006

Pesquisa de arquivos




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ção

faReadOnly arquivos marcados como "somente leitura"
faHidden arquivos ocultos
faSysFile arquivos do sistema
faVolumeID arquivos" que representam drives - C, D, A..
faDirectory diretórios (sim, são arquivos)
faArchive arquivos de arquivamento - será isso?
faAnyFile qualquer um dos citados


O 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 = record
Time: Integer;
Size: Integer;
Attr: Integer;
Name: TFileName;
ExcludeAttr: Integer;
FindHandle: THandle;
FindData: TWin32FindData;
end;


Abaixo, o código fonte:




unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FileCtrl, ExtCtrls;

type
TForm1 = 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;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FindFiles(const sDirectory: string;
const SearchSubfolders: boolean = true);
var
sr: TSearchRec;
begin
if DirectoryExists(sDirectory) then
try
if Recursive <= 0 then
begin
StartTime:= GetTickCount;
Recursive:= 0;
ListBox1.Clear;
ListBox1.Items.Add('Procurando por '+edit1.Text);
end;

if SysUtils.FindFirst(sDirectory+'\*.*',
faAnyFile, sr) = 0 then
begin
repeat
case sr.Attr of
faDirectory:
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;

finally
SysUtils.FindClose(sr);
Dec(Recursive);
if Recursive < 0 then
begin
ListBox1.Items.Add('Terminado em '
+IntToStr(GetTickCount - StartTime)+'ms.');
ListBox1.ItemIndex:= ListBox1.Count-1;
end;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
FindFiles( DirectoryListBox1.Directory, CheckBox1.Checked);
end;

end.

Código fonte transformado em HTML por http://tohtml.com/pascal/


Gostou? Sugere alguma coisa? Comente!

1 Comentários:

Anonymous Anônimo disse ...

Interessantes os artigos desse blog =)

esse por exemplo, explica um função q eu já utilizei em um projeto.. porém não tinha entendido direito como era seu funcionamento (no meio da correria de terminar, vc acaba pegnado pronto)

Continue assim por favor.. é muito bom aprender coisas novas

3:21 PM  

Postar um comentário

<< Home

Pesquisa no Blog:
Web DelphiEArte.blogspot.com