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

Как определить подключён ли компьютер к интернету

Поиск файлов на 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.

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



Опубликовал admin
30 Май, Пятница 2003г.



Программирование для чайников.