Урок22. Программный поиск файлов
В этом уроке мы с вами ознакомимся с основными принципами программной организации поиска файлов. Для начала определимся, зачем нам это может быть нужно. Например, вам нужно при запуске программы на выполнение просканировать определенный каталог на присутствие DOC файлов, и при наличии таковых открыть их на редактирование или напечатать. А как вам такая идея: фоновый поиск EXE файла в сети, и при обнаружении новой версии, автоматическое обновление.
Вспомним правила поиска файлов. Вы можете задать как имя искомого файла, так и его маску, если название неизвестно или необходимо найти несколько. Т.е. применяя специальный шаблон поиска, вы можете организовать условия выборки найденных файлов. Сразу оговорюсь, что поиск можно применять как к файлам, так и к каталогам. Будем их называть элементами файловой системы. В шаблон маски искомых элементов может входить: Теперь рассмотрим программный поиск файлов с помощью языка программирования object pascal. Вся организация цикла поиска, а именно это и есть цикл с продолжением поиска, сводится к: Функция FindFirst. Синтаксис: FindFirst (КАТАЛОГ_ПОИСКА_И_МАСКА_ФАЙЛА, АТРИБУТЫ_ИСКОМОГО_ФАЙЛА, ПОИСКОВОЯ_ПЕРЕМЕННАЯ); где: Каталог для поиска и маска искомого элемента - строковая величина, имеющая тип String, может, например, содержать 'c:\*.*' - все элементы в корне диска С. Обратите внимание, что указывается полный путь для поиска. Атрибуты искомого элемента это пользовательские или системные атрибуты, которые может иметь файл (каталог, метка диска). Вот их перечень: Поисковая переменная имеет тип TSearchRec. В нее, при успешном результате поиска, будет занесены все необходимые данные о найденном файловом элементе. Поскольку FindFirst является функцией, то она должна сама возвращать некоторое значение. Это значение имеет тип Integer и означает результат поиска файла (код ошибки поиска). Если файл найден, то принимает нулевое значение. Функция FindNext. FindNext (ПОИСКОВАЯ_ПЕРЕМЕННАЯ); Эта функция продолжает поиск, заданный в функции FindNext. Возвращает значение результата поиска (нулевое в случае успешного поиска). Процедура FindClose. FindClose (ПОИСКОВАЯ_ПЕРЕМЕННАЯ); Закрывает поиск и освобождает память, выделенную системой под поиск. Теперь рассмотрим пример. Допустим, нам надо найти все файлы и каталоги в каталоге DELPHI, находящийся на диске C:. В дальнейшем, вы можете самостоятельно, изменяя маску, менять условия поиска. Для формы с компонентом ListBox1 и кнопкой Button1 реакция на OnClick по кнопке: procedure TForm1.Button1Click(Sender: TObject); FindRes:=FindFirst('c:\delphi\*.*',faAnyFile,SR); // задание условий поиска и начало поиска While FindRes=0 do // пока мы находим файлы (каталоги), то выполнять цикл Представленный пример кода, в принципе, является основой для организации более углубленного поиска, поиска файлов по времени создания, по содержащимся словам. Если вы запустите эту программу на выполнение, то при нажатии на кнопку Button1 вы увидите в списке в первой и второй строке элементы "." и "..". Это элементы, имеющие атрибут "каталог". Первый содержит связь с корневым каталогом диска, второй содержит связь к каталогом верхнего уровня. Со вторым вы встречаетесь в дисковых командных оболочках, например нортон, когда выбираете каталог ".." и нажимаете на "ввод". Тем самым вы попадаете в каталог на уровень выше. Естественно, в нашей поисковой программе такие элементы не надо вносить в список, поэтому мы игнорируем их нахождение. Исправляем процедуру нажатия на кнопку Button1: procedure TForm1.Button1Click(Sender: TObject); FindRes:=FindFirst('c:\delphi\*.*',faAnyFile,SR); ListBox1.Items.Add(SR.Name); В этом случае, при нахождении каталога с именем "." или с именем ".." программа продолжит обработку цикла поиска без вывода найденного имени элемента в компонент списка ListBox1. Теперь рассмотрим тип TSearchRec. Он имеет в себе несколько полезных свойств: Все вышеперечисленные свойства мы уже рассмотрели или они понятны сразу, за исключением свойства Time. Оно имеет тип Integer и содержит в себе упакованное значение даты и времени создания файла. Распаковка производится с помощью функции FileDateToDateTime, которая в результате возвращает значение даты и времени. procedure TForm1.Button1Click(Sender: TObject); FindRes:=FindFirst('c:\delphi\*.*',faAnyFile,SR); ListBox1.Items.Add(SR.Name); Как вы уже заметили, мы отбираем файлы и каталоги по дате создания, начиная с указанной в компоненте DateTimePicker1. Теперь попробуем организовать поиск файлов во всех вложенных каталогах. Это не так просто, как может показаться на первый взгляд. Нам придется вручную организовывать весь цикл входа-выхода из каталога, перебор файлов. Немного сложноватый материал, но возможно те из вас, кто уже работал с языком программирования pascal или другим, знакомы с технологией многократности и многовложенности использования одного и того же программного кода. Коротко объясню алгоритм работы такой программы. Рассмотрим пример. Создайте новый проект. Для создания отдельной процедуры поиска нам нужно объявить ее в соответствующем разделе (создаем ее вручную, поэтому и самостоятельно объявляем). В разделе public пишем строку: procedure FindFile(Dir:String); А в разделе кода программы, до слова "end." вставляем пустой каркас процедуры procedure TForm1.FindFile(Dir:String); end; На форму вставляем компонент списка ListBox1, Button1, Edit1. Для компонента Edit1 свойство Text устанавливаем в "c:\delphi\". Обратите внимание на последний символ, знак "\", присутствие которого в начальном пути поиска обязательно. Дальше процедура OnClick для кнопки Button1 выглядит следующим образом: procedure TForm1.Button1Click(Sender: TObject); Созданная нами вручную процедура поиска: procedure TForm1.FindFile(Dir:String); if ((SR.Attr and faDirectory)=faDirectory) then // если найден каталог, то ListBox1.Items.Add(SR.Name); Если вы в компоненте Edit1 в качестве начального условия поиска файлов зададите корневую папку диска, например "С:\", то вы получите полный перечень всех файлов на данном диске. Обратите внимание на скорость поиска файлов и скорость работы вашей программы. С уважением, ведущий уроков Semen semen@krovatka.net
|