Урок Delphi 7
Работа с файлами в Delphi

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


Компоненты работающие с файлами
Классическая работа с файлами
Диалоги выбора файлов
Определение размера файла
Поиск файлов
Таблица функций






Уроки Delphi
  1.  Первая программа
  2.  Использование компонентов
  3.  События Delphi
  4.  Типы данных Delphi
  5.  Создание своих типов данных
  6.  Выражения и операторы
  7.  Работа с файлами в Delphi
  8.  Дополнительные формы
  9.  Подпрограммы в Delphi
  10. Исключительные ситуации
  11. Взаимодействие приложения с пользователем
  12. Указатели в Delphi
  13. Обзор компонентов
  14. Работа со строками
  15. Создание интерфейса
  16. Графика в Delphi
  17. Многопоточность в Delphi
  18. Динамическое создание
        компонентов
Поиск по сайту




 Это важно:
   Метод Application.ProcessMessages;

 Это полезно:
   Параметр Sender в обработчиках событий;










Бояться не надо



   Поиск файлов в Delphi поможет найти файлы, подходящие по выбранным программистом критериям - имени, размеру, дате создания и т.д. Поиск файлов может производиться как по всему выбранному диску, так и ограничиться отдельным каталогом. Поиск файлов в Delphi выполняется в три этапа.

  1. Сначала находится первый файл, удовлетворяющий заданной маске. Этот поиск осуществляется с помощью функции
      function FindFirst(const Path: String; Attr: Integer; var F: TSearchRec): Integer;

    Параметр Path задаёт адрес каталога (директории), в котором производится поиск. Он должен завершаться маской имён искомых файлов, например:
      'C:\Temp\*.*', '*.txt'.
    Символ '*' означает любое количество допустимых в имени файла символов. Если необходимо указать, что символ должен быть только один, то в маске используется символ '?'. Например, маска a*.txt определяет текстовые файлы с именем любой длины начинающиеся на a, а маска a?.txt ограничивает длину имени файлов двумя символами. Если в маске описан только файл, то поиск осуществляется только в текущем каталоге.

    Параметр Attr содержит набор атрибутов, которые могут учитываться при отборе файлов:

    • faReadOnly = $01 - файл только для чтения;
    • faHidden = $02 - скрытый файл;
    • faSysFile = $04 - системный файл;
    • faVolumeID = $08 - метка диска;
    • faDirectory = $10 - каталог (директория);
    • faArchive = $20 - архивный файл;
    • faAnyFile = $3F - произвольный файл.

       Наименования этих атрибутов могут иметь различные имена в различных системах. Именно текое предупреждение выдаёт Delphi при попытке использовать эти имена. Поэтому лучше использовать не наименования, а значения. Однако, тогда возникают непонятки: попробуй догадайся впоследствии, что такое $02 или $08... Поэтому нужно вводить константы с сответствующими значениями, и проблем не будет.

       Эти атрибуты имеют значение отдельных битов в результирующем числе Attr. Для задания искомому файлу набора атрибутов их нужно просто просуммировать:
      Attr := faReadOnly + faSysFile + faHidden;
    Такой набор атрибутов заставит функцию искать только скрытые системные файлы с характеристикой "только для чтения".

    Результат поиска содержится в переменной F, имеющей тип TSearchRec:
      type TSearchRec = record
        Time: Integer;
        Size: Integer;
        Attr: Integer;
        Name: TFileName;
        ExcludeAttr: Integer;
        FindHandle: THandle;
        FindData: TWin32FindData;
      end;


    Наиболее важными среди полей этой записи являются:

    • Name - имя файла;
    • Size - Размер файла в байтах;
    • Time - время создания файла в формате DOS.

  2. Чтобы определить, имеет ли найденный файл нужный атрибут, используется поразрядное логическое умножение:
      if (F.Attr and faDyrectory)=F.Attr
        then S:='Это каталог';

    То есть, имеющая нужный атрибут переменная F.Attr при поразрядном логическом умножении на него не изменяется.

  3. Когда первый файл, удовлетворяющий условиям поиска, найден, вызывается функция
      function FindNext(var F: TSearchRec): Integer;

    Переменная F, в которой первая функция сохранила результат поиска, передаётся функции FindNext в качестве параметра. На основании записанной в неё информации будет продолжен поиск следующего подходящего файла.

  4. Процесс поиска завершается вызовом процедуры:
      procedure FindClose(var F: TSearchRec);

    Эта процедура освобождает память, которая была выделена системой для проведения процесса поиска.

   Функции FindFirst и FindNext возвращают значение 0, если при поиске не возникло ошибок и очередной файл был найден.

   Программы, в которых предусмотрены функции поиска файлов, известны давно. Это, например, файловые коммандеры (volkov commander, norton commander, dos navigator, far). Также функция поиска файлов есть во всех операционных системах. В частности, в Windows поиск файлов вызывается через ПУСК - Поиск - Файлы и папки. В диалоговом окне поиска пользователю нужно задать, каким образом будет искаться файл: имя или маска и каталог начального поиска. Также есть возможноть уточнить дату изменения, содержащийся в файле текст, предполагаемый размер файла.

   А теперь ещё раз посмотрим, как в delphi происходит поиск файлов. Если пока непонятно, зачем это может потребоваться, вот несколько вариантов. Например, при запуске программы нужно проверить наличие необходимых для работы программы файлов. Или в фоновом режиме поиск источников обновления программы, или поиск файлов, содержащих результаты работы контролируемых программ, и т.д.

   Основным в процедуре поиска файлов являются правила задания имени файлов для поиска. В качестве искомого можно задать как непосредственно имя файла, так и маску имени, если название точно не известно или может иметься несколько файлов, подходящих под критерии поиска. Тем самым мы задаём специальные шаблоны поиска, в которых содержатся условия выборки найденных в процессе поиска файлов. Естественно, можно искать как файлы, так и целые директории, то есть все элементы файловой системы компьютера.

   Шаблон маски файлов может содержать:
  • Латинские буквы и цифры в названии и расширении файла;
  • Символ * (звездочка), который здесь служит заменой любого количества символов в названии или расширении файла;
  • Символ ? (знак вопроса). В маске этот символ заменяет только один символ в названии или расширении файла или директории.
   Приведём примеры. Если нужно найти все текстовые файлы (файлы с расширением TXT), то маска поиска будет такая: *.txt. Если нужно найти файлы, в названии которых содержится слово, например, vovan, то маска будет содержать это слово и символы * в начале и в конце, предусматривающие возможное наличие других символов в начале и в конце имени файла, а также в расширении: *vovan*.*. Если в имени файла первая буква a, а четвёртая b, то маску сконструируем такую: a??b*.*

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

   Для примера рассмотрим простую программку, которая поизводит поиск всех файлов на диске C. В программе папка рассматривается как файл, внутрь поиск не лезет. Можно скачать архив с этой программой.


Предыдущий урок           В начало урока          Следующий урок  

Уроки Delphi начинающим



Вопросы и комментарии (24)      Решение задач в Delphi

Одиссей, добавлено 3.08.10, 13:48:30 
Скачал демонстрационную программу. Интересно, почему некоторые каталоги на диске с: не были отмечены как каталоги, и не указан их размер, например, папка Program Files?
Автор, добавлено 3.08.10, 13:51:53 
Действительно, я думаю, это причуда системы Windows. Наверное, она не хочет показывать данные своих особенно важных папок. С другой стороны, сам каталог Windows был найден именно как папка. Надо подумать над этим вопросом.
Зелёный, добавлено 14.11.10, 10:47:59 
А мне нужно сделать в программе поиск информации на компе пользователя. Как это осуществить?
Автор, добавлено 14.11.10, 11:02:15 
Ну, для начала нужно определить, сколько дисков находится в компьютере. Потом задать программу поиска последовательно по всем дискам всех файлов, или можно спросить пользователя, желает ли он искать также в системных и скрытых файлах. Как это сделать, читайте выше в тексте урока. Найденные файлы записывайте в список или таблицу. Затем уже (или даже параллельно, но для этого нужно освоить многопоточную работу) можно загружать найденный файл например в stringlist или Memo и искать в тексте нужную фразу - просто с помощью функции pos. Если фраза найдена, выводить этот файл пред ясны очи пользователя.
Ничего заумного, но подумать самому придётся.
Зелёный, добавлено 14.11.10, 12:15:00 
Спасибо за ответ, план ясен. Начну потихоньку, а если что, могу рассчитывать на вашу помощь?
Автор, добавлено 14.11.10, 12:30:31 
Поиск файлов и поиск в файлах - интересная тема. Конечно, помогу чем смогу, но предупреждаю сразу, за вас ничего кодировать не стану.
Newsman, добавлено 22.12.10, 07:39:33 
А как перейти на тот диск, на котором требуется искать? Ведь если искать по всему содержимому комьютера, требуется определить сколько дисков в системе и их имена...
Автор, добавлено 22.12.10, 08:45:43 
Для определения дисковой структуры можно использовать разные способы, например, воспользоваться функцией DirectoryExsists, проверяя наличие корневой директории:
 
  if DirectoryExists('C:\') //Или просто 'C:'
    then Caption:='Диск C в системе';

И перебрать все буквы от A до Z. Правда, если гибкого диска в дисководе А не будет, он не определится, конечно. Но А можно и пропустить. Но есть и более продвинутые способы, с помощью WinAPI функции GetLogicalDrives. Бросим на Форму кнопку Button и список ListBox. С помощью процедур:

function DriveExists (Drive: Byte) : boolean;
begin
Result := Boolean (GetLogicalDrives and (1 shl Drive));
end;

procedure TForm1.Button1Click(Sender: TObject);
var Drive : byte;
begin
for Drive := 0 to 25 do
  if DriveExists (Drive) then
  ListBox1.Items.Add (Chr(Drive+$41));
end;


нажав на кнопку, в компоненте ListBox получим всю структуру дисков в компьютере.
Дэц, добавлено 8.01.12, 13:43:45 
А как сделать так, чтобы можно было обработать найденные файлы, переместить их к примеру.
Автор, добавлено 8.01.12, 17:59:36 
Вверху есть ссылка Таблица функций, там приведены функции для работы с файлами.
Аноним, добавлено 2.05.12, 01:20:43 
Спасибо!)
Николай, добавлено 22.09.13, 08:12:15 
Ни чо не понял.
Автор, добавлено 22.09.13, 21:11:16 
А просто читать недостаточно. Нужно пробовать самому, "ручками", сделать как написано. После нескольких проб и ошибок поймёшь. Другого способа понять нет. Только когда сам...
Евгений, добавлено 3.11.13, 05:33:11 
Здравствуйте! Подскажите пожалуйста как создать файл в под папке? Я создал несколько глобальных переменных и главную для основной папки в которой будут остальные. Код ниже создаёт только одну папку, а как поместить туда все папки я не знаю (я прибавил имя папки программа пишет путь не найден)
FilesSAMPServers:=ExtractFilePath(ParamStr(0))+'\Файлы SAMPServers\Имена серверов';
  CreateDir(FilesSAMPServers);
  If FileExists(FilesSAMPServers+'\Имена серверов.ini') then
  begin
  CreateDir(FilesSAMPServers);
  sDBComboBox1.Items.LoadFromFile(FilesSAMPServers+'\Имена серверов.ini');
Автор, добавлено 3.11.13, 09:10:00 
Не совсем понятно, почему у вас

CreateDir(FilesSAMPServers);// - папка создаётся
  If FileExists(FilesSAMPServers+'\Имена серверов.ini') then// - откуда в только что созданной папке возьмётся файл?
  begin
  CreateDir(FilesSAMPServers);// - папка создаётся повторно?

А файл создаётся оператором Rewrite. Почитайте урок "Классическая работа с файлами". Но вначале нужно создать его структуру, тип. Если это текстовый файл, то проще работать с компонентом Memo.
Евгений, добавлено 3.11.13, 10:48:13 
Я в sDBComboBox1 создаю стринглист
var
SL: TStringList;
S: String;
begin
  SL:=TStringList.Create;
  SL.Add(S);
  S:=sDBComboBox1.Text;
  sDBComboBox1.Items.Add(S);
  sDBComboBox1.Items.SaveToFile('Имена серверов.ini');
 end;
Евгений, добавлено 3.11.13, 11:04:45 
Я вероятно не верно выразился с созданием файла проблем нет мне нужно папку с файлом поместить в главную папку, которая создаётся в директории с программой в которой создастся ещё столько папок сколько создастся файлов.
Автор, добавлено 3.11.13, 11:09:29 
Ну и что? Не понимаю вас. И что тут у вас:

SL:=TStringList.Create;
  SL.Add(S);//S не определено, чего мы записали?
  S:=sDBComboBox1.Text;//это текст бокса
  sDBComboBox1.Items.Add(S);//не проще сразу в бокс записать его текст:

with sDBComboBox1 do
  Items.Add(Text);


Насчёт того, как запихнуть папку в папку - нужно её там создать. Вот код, создающий папку А, в ней ещё одну А, а в ней ещё одну:

CreateDir('A');
CreateDir('A\A');
CreateDir('A\A\A');

SaveToFile('A\A\A\file.ini');//сохраняет файл

Таким образом, мы не копируем папку с файлом, а создаём внутри нужной папки ещё сколько хотим папок, и туда сохраняем или копируем файл. А лишние исходные папки удаляем.
Евгений, добавлено 3.11.13, 11:27:22 
Спасибо большое просто я папку через переменную создать пытался.
А на счёт ветви папок, я имел ввиду:
CreateDir('A\A1\file.ini');
CreateDir('B\B1\file.ini');
CreateDir('C\C1\file.ini');
CreateDir('D\D1\file.ini');
Евгений, добавлено 3.11.13, 11:49:12 
Мне не удаётся создать путь SaveToFile('A\A\file.ini') система его не находит
просто мне нужно чтобы программа создавала его в директории с программой в этом и заключается проблема.
Автор, добавлено 3.11.13, 11:57:52 
Да, это проблема. Есть понятие текущей директории - именно туда система сохраняет файлы, адреса которых заданы неявно. И иногда непонятно, какая директория (папка) в данный момент является текущей. Поэтому я лично в НЕ Тестовых приложениях всегда указываю директории явно, задавая полный адрес. Папка вашей программы (.exe файла):

FilePath:=ExtractFilePath(Application.ExeName);

Поэтому адрес файла в этой папке

FileName:=FilePath+'file.ini';

Насчёт слеша не уверен, но вроде он не нужен, проверьте.
Евгений, добавлено 3.11.13, 12:22:19 
Я не уверен, что правильно понял код но вот что у меня получилось
 begin
  FilePath:=ExtractFilePath(Application.ExeName);
  FileName:=FilePath+'file.ini';
  CreateDir(FilePath+'file.ini');
  If FileExists(FilePath+'file.ini') then
  begin
  sDBComboBox1.Items.LoadFromFile(FilePath+'file.ini');
  end;
 end;
Автор, добавлено 3.11.13, 12:42:30 
FilePath:=ExtractFilePath(Application.ExeName); // - это адрес папки с вашим exe-файлом
FileName:=FilePath+'file.ini'; // - это имя файла в в данной папке
CreateDir(FilePath+'file.ini'); //то что в скобках это FileName (строчка выше), что за хрень, вы по имени файла создаёте папку
 If FileExists(FilePath+'file.ini') then //проверяете наличие файла - его нет, вы папку создали, а не файл
sDBComboBox1.Items.LoadFromFile(FilePath+'file.ini'); //загружаете из файла??? Даже если бы он и был создан - был бы пуст, чего из него загружать???
Оставить комментарий:

Имя  

Текст комментария