Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Функция FindFirst и поиск файлов с длинными именами в Delphi и Pascal

Delphi , Файловая система , Файлы

 

Ошибка компиляции при использовании Assign для поиска файлов

В недавнем обсуждении на форуме разработчиков Pascal возникла проблема с компиляцией кода, использующего функцию FindFirst для поиска файлов. Основная ошибка заключалась в сообщении компилятора: "Error: Can't determine which overloaded function to call" при попытке использовать Assign с параметром Find.WinFindData.cFileName.

Анализ проблемы

Исходный код выглядел следующим образом:

Program Finderror1;
   Uses Dos;
   Var F1,F2:Text;
    F3:Text;
    T1:String;
    Find:SearchRec;
    FA:Byte;
 Begin
  AsSign(F1,'A.Txt');ReSet(F1);
  ReadLn(F1,T1);
  AsSign(F2,'B.Txt');ReWrite(F2);
  FindFirst(T1,$3F,Find);
  Repeat
    If FA=0
      Then Begin WriteLn(F2,'FA is 0');
                 FindNext(Find);End
      Else Begin AsSign(F3,Find.WinFindData.cFileName);
                 ReSet(F3);
                 Close(F3);
    End;
  Until Dos.DosError=18;
  Close(F1);Close(F2);
  FindClose(Find);
End.

Основные проблемы в этом коде:

  1. Использование устаревшего модуля Dos вместо SysUtils
  2. Попытка использовать Find.WinFindData.cFileName, который не совместим с типом SearchRec
  3. Неинициализированная переменная FA
  4. Неправильная обработка ошибок

Решение проблемы

1. Использование модуля SysUtils

Современные версии Delphi и Free Pascal рекомендуют использовать модуль SysUtils вместо устаревшего Dos. Вот исправленный вариант кода:

program FileSearchExample;
uses
  SysUtils;

var
  F1, F2, F3: TextFile;
  T1: String;
  Find: TSearchRec;
  SearchResult: Integer;
begin
  AssignFile(F1, 'A.Txt');
  Reset(F1);
  try
    ReadLn(F1, T1);
  finally
    CloseFile(F1);
  end;

  AssignFile(F2, 'B.Txt');
  Rewrite(F2);
  try
    SearchResult := FindFirst(T1, faAnyFile, Find);
    try
      while SearchResult = 0 do
      begin
        try
          AssignFile(F3, Find.Name);
          Reset(F3);
          try
            // Обработка файла F3
          finally
            CloseFile(F3);
          end;
        except
          on E: EInOutError do
            WriteLn(F2, 'Ошибка при обработке файла: ', Find.Name);
        end;
        SearchResult := FindNext(Find);
      end;
    finally
      FindClose(Find);
    end;
  finally
    CloseFile(F2);
  end;
end.

2. Работа с длинными именами файлов

Для работы с длинными именами файлов (более 256 символов) в Windows можно использовать следующие подходы:

  1. Использование префикса \\?\:
     function LongPath(const Path: string): string;
    begin
    if Pos('\?\', Path) = 1 then
    Result := Path
    else
    Result := '\?\' + Path;
    end;
    // Пример использования AssignFile(F3, LongPath(Find.Name)); 
  2. Использование Unicode-версий функций: В современных версиях Delphi и FPC (с режимом {$MODE DELPHIUNICODE}) строки по умолчанию являются Unicode-строками, что позволяет работать с длинными путями.

3. Альтернативный подход с TDirectory

Для более современного подхода к поиску файлов можно использовать класс TDirectory из модуля IOUtils (доступен в Delphi XE и новее, а также в Free Pascal с соответствующими настройками):

uses
  System.IOUtils;

var
  Files: TStringDynArray;
  FileName: string;
begin
  Files := TDirectory.GetFiles('C:\Path\To\Search', '*.*', TSearchOption.soAllDirectories);
  for FileName in Files do
  begin
    // Обработка каждого найденного файла
  end;
end;

Пример поиска файлов с обработкой длинных путей

Вот полный пример программы для поиска файлов с поддержкой длинных путей:

program AdvancedFileSearch;

{$APPTYPE CONSOLE}
{$MODE DELPHI}

uses
  SysUtils, Windows;

function IsLongPath(const Path: string): Boolean;
begin
  Result := (Length(Path) > MAX_PATH) or (Pos('\\?\', Path) = 1);
end;

function EnsureLongPath(const Path: string): string;
begin
  if IsLongPath(Path) then
    Result := Path
  else if (Length(Path) >= MAX_PATH) or (Pos('\\', Path) = 1) then
    Result := '\\?\' + Path
  else
    Result := Path;
end;

procedure SearchFiles(const Pattern: string);
var
  SearchRec: TSearchRec;
  SearchResult: Integer;
  LongPattern: string;
begin
  LongPattern := EnsureLongPath(Pattern);

  SearchResult := FindFirst(LongPattern, faAnyFile, SearchRec);
  try
    while SearchResult = 0 do
    begin
      if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
      begin
        if (SearchRec.Attr and faDirectory) = 0 then
          Writeln('Файл: ', SearchRec.Name)
        else
          Writeln('Каталог: ', SearchRec.Name);
      end;
      SearchResult := FindNext(SearchRec);
    end;
  finally
    FindClose(SearchRec);
  end;
end;

begin
  try
    WriteLn('Поиск файлов с поддержкой длинных путей');
    SearchFiles('C:\Temp\*.*');
    SearchFiles('\\?\C:\VeryLongPath\WithManySubdirectories\*.*');
  except
    on E: Exception do
      Writeln('Ошибка: ', E.Message);
  end;
  ReadLn;
end.

Заключение

При работе с поиском файлов в Delphi и Pascal следует:

  1. Использовать модуль SysUtils вместо устаревшего Dos
  2. Для работы с длинными именами файлов применять префикс \\?\ или Unicode-строки
  3. Всегда закрывать дескрипторы поиска с помощью FindClose
  4. Обрабатывать возможные ошибки ввода-вывода
  5. Рассмотреть использование более современных подходов, таких как TDirectory из IOUtils

Соблюдение этих рекомендаций поможет избежать ошибок компиляции и проблем с обработкой файлов, особенно при работе с длинными путями в современных операционных системах.

Создано по материалам из источника по ссылке.

Описание проблемы и решений для работы с функцией FindFirst и длинными именами файлов в Delphi и Pascal.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Файлы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-12 15:18:08/0.007627010345459/1