Поиск файлов на Delphi

В этой статье мы познакомимся с функциями для поиска файлов на дисках Вашего (и не только :) компьютера. Для тех кто собирается писать вирусы или что-то подобное используя приведенный алгоритм, то предупреждаю: создание вредоносных программ карается по УК РФ!!! Так что думайте сами, а тем кому интересно как же найти файл на диске с помощью Дельфи, то читайте дальше...

Для поиска файлов на диске в Delphi существует две функции, первая из них - это FindFirst, ниже приведено ее описание:


function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;  

Path - путь, по которому искать файл, включая его имя и расширение (возможно использовать символ *).

attr - атрибуты файла. Может принимать следующие значения:

faReadOnly $00000001 Только чтение
faHidden $00000002 Скрытый
faSysFile $00000004 Системный
faVolumeID $00000008 Метка диска
faDirectory $00000010 Директория
faArchive $00000020 Обычный
faAnyFile $0000003F Любой файл

F- переменная типа TsearchRec, в нее Delphi запихивает все характеристики найденного файла. Описание типа TsearchRec (предлагаю только для того, чтобы было проще освоиться, сам тип уже описан в SysUtils).


type  
    TSearchRec = record  
    Time: Integer; // время создания  
    Size: Integer; //размер файла в байтах  
    Attr: Integer; // Атрибуты  
    Name: TFileName; //имя файла  
    ExcludeAttr: Integer;   
    FindHandle: THandle; //хандл на файл  
    FindData: TWin32FindData; //доп. информация о файле  
end;  

Теперь приведу простой пример использования этой функции. Поставьте на форму одну кнопку TButton, а обработчик события OnClick у нее должен иметь примерно такой вид:


procedure TForm1.Button1Click(Sender: TObject);  
 var sr:TSearchRec;  
 begin  
 findFirst('*.exe',faAnyFile,sr);  
 edit1.Text:=sr.Name;  
 end;  

Чтобы искать следующий такой же файл, надо написать FindNext (Sr); Если файл найден, то процедуры FindFirst и FindNext возвращают 0 (зеро).

Ну а теперь собственно о том, как можно применить эти функции на практике, то есть опять пример!!! Чтобы разобраться с использованием этих функций попробуем написать программку, которая выдавала список всех программ с расширением *.exe в указанной директории, а затем при нажатии на кнопку включалась бы выбранная программа. На примере я покажу, как найти все .exe файлы в директории Windows, а затем объясню как можно модифицировать программку!

Итак, ставим на форму компонент TListBox в него мы будем выводить список найденных файлов. Обработчик события OnClick для нашей первой кнопки заменяем на такой:


procedure TForm1.Button1Click(Sender: TObject);  
var sr:TSearchRec;  
Result:word;  
begin  
    ChDir('C:\windows');//меняем папку на C:\Windows  
    Result := FindFirst ('*.exe',faAnyFile,sr);  
    ListBox1.Clear;  
    While result=0 do  
Begin  
    Result:=FindNext (sr);  
    ListBox1.Items.add(sr.name);  
End;  
end;  

Как видите мы просто организовали цикличный проход по директории C:\Windows, который прекращается, как только функции возвращает не ноль! Функция ChDir была использована для смены папки с текущей на папку C:\windows\

Но приведенный выше способ находит файлы лишь в том каталоге, который задан переменной Path:String. Мне кажется, этого недостаточно для решения большей части поисковых проблем, поэтому стоит написать алгоритм поиска файлов в каждой найденной директории.

У меня расширенная процедура поиска выглядит вот так:


procedure ffind(cat:string); //каталог, откуда начать поиск  
var sea:TSearchRec;  
res:integer; //результат поиска (0 или нет)  
begin  
res:=FindFirst(cat+'*.*',faAnyFile,sea); //ищем первый файл  
res:=findNext(sea);//ищем следующий файл  
While res=0 do  
begin  
if (Sea.Attr=faDirectory) and ((Sea.Name='.')or(Sea.Name='..')) then//чтобы не было файлов . и..  
begin  
Res:=FindNext(sea);  
Continue;//продолжаем цикл  
end;  
  
if (Sea.Attr=faDirectory) then//если нашли директорию, то ищем файлы в ней  
begin  
Ffind(cat+Sea.Name+'\');//рекурсивно вызываем нашу процедуру  
Res:=FindNext(Sea);//ищем след. файл  
Continue;//продолжаем цикл  
end;  
form1.ListBox1.Items.Add(Sea.Name);//добавляем в Listbox:Tlistbox имя файла  
Res:=FindNext(Sea);//ищем след. файл  
end;  
FindClose(Sea);//освобождаем пересенную поиска  
end;  

Здесь была использована процедура FindClose(var sea: TsearchRec); она необходима для освобождения поисковой переменной. В следующих примерах ее я использовать не буду, но Вы имейте ее в виду!!!

Возможно, этот алгоритм не самый быстрый и удобный, но он работает.
Для того, чтобы ваше приложение не выглядело подвисшим, можно добавить Application.ProcessMessages в начало нашей процедуры.

Теперь поставьте на форму еще кнопку для того, чтобы по ее нажатии запускать выбранную в ListBox'e программу. Обработчик события Onclick для нашей второй кнопки у меня получился таким:


procedure TForm1.Button2Click(Sender: TObject);  
begin  
    WinExec(pchar(listbox1.Items[listbox1.itemindex]),sw_show);  
end;  

Поскольку файлы находятся в директории Windows, то при вызове метода WinExec путь к файлам можно не указывать, а если вы используете какую-либо другую директорию, то вызов метода WinExec должен быть примерно таким:


WinExec(pchar('C:\Путь к вашей папке\'+listbox1.Items[listbox1.itemindex]),sw_show);   

Ну если вы хотите искать файлы в указанном пользователем каталоге можно использовать компонент DirectoryListBox, который дает доступ к каталогам на вашем компьютере и позволяет менять текущий каталог двойным нажатием мыши. Узнать выбранный каталог можно так:


DirectoryListBox1.Directory  

Поэтому в обработчике первой кнопки нужно убрать вызов функции ChDir. А в обработчике второй кнопки вставить приведенную выше конструкцию.

Таким образом приведу полный код приложения, которое получилось у меня с использованием компонента DirectoryListBox


unit Unit1;  
  
interface  
  
uses  
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  
StdCtrls, FileCtrl;  
  
type  
TForm1 = class(TForm)  
Edit1: TEdit;  
Button1: TButton;  
ListBox1: TListBox;  
Button2: TButton;  
DirectoryListBox1: TDirectoryListBox;  
procedure Button1Click(Sender: TObject);  
procedure Button2Click(Sender: TObject);  
private  
{ Private declarations }  
public  
{ Public declarations }  
end;  
  
var  
Form1: TForm1;  
  
implementation  
  
{$R *.DFM}  
  
procedure TForm1.Button1Click(Sender: TObject);  
var sr:TSearchRec;  
Result:word;  
begin  
Result := FindFirst ('*.exe',faAnyFile,sr);  
ListBox1.Clear;  
While result=0 do  
Begin  
Result:=FindNext (sr);  
ListBox1.Items.add(sr.name);  
End;  
end;  
  
procedure TForm1.Button2Click(Sender: TObject);  
begin  
WinExec(pchar(DirectoryListBox1.Directory+'\'+listbox1.Items[listbox1.itemindex]),sw_show);  
end;  
  
end.  

Ну вот и все :)) Надеюсь, что помог Вам своими рассуждениями и примерами!

Автор: Михаил Христосенко
Теги:
Поиск файлов
Добавлено: 04 Августа 2018 08:37:56 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...