При работе с компонентом Indy FTP в Delphi пользователи могут столкнуться с проблемой некорректного получения списка файлов на FTP-сервере. В этой статье мы рассмотрим причину этой проблемы и предложим решение.
Описание проблемы
При использовании метода TIdFTP.List для получения списка файлов на FTP-сервере пользователи могут столкнуться со следующей ошибкой:
EidReplyRFCError with message '_._': No such file or directory.
При этом, если вызывать метод без параметров или с параметром '.', он работает корректно. Однако, если указать конкретную маску файлов, например '*.zip', метод вызывает ошибку. Например:
FTP.List(aFiles, '', true); // это работает
FTP.List(aFiles, '*.*', false); // это тоже работает
FTP.List(aFiles, '*.*', true); // это вызывает ошибку
FTP.List(aFiles, '*.zip', true); // это тоже вызывает ошибку
FTP.List('*.*', false); // это работает
FTP.List('*.*', true); // это вызывает ошибку
Причина проблемы
Причиной проблемы является несоответствие между документацией Indy и фактической работой метода TIdFTP.List. В зависимости от значений свойств ADetails, TIdFTP.UseMLIS и TIdFTP.CanUseMLS, метод TIdFTP.List может отправлять на сервер разные команды: NLST, LIST или MLSD. При этом, если указать в качестве параметра маску файлов, сервер может вернуть ошибку, если не поддерживает фильтрацию по маске в ответе на команду MLSD.
Решение проблемы
Чтобы решить проблему, нужно учитывать, какую команду отправляет метод TIdFTP.List на сервер. Если сервер поддерживает команду MLSD и свойства TIdFTP.UseMLIS и TIdFTP.CanUseMLS установлены в True, метод отправляет команду MLSD. В этом случае параметр ASpecifier должен быть пустым или указывать на директорию, а не на маску файлов.
Если сервер не поддерживает команду MLSD или свойства TIdFTP.UseMLIS и TIdFTP.CanUseMLS установлены в False, метод отправляет команду LIST или NLST. В этом случае параметр ASpecifier может указывать на маску файлов.
В качестве альтернативного решения можно использовать все доступные парсеры списков файлов, включив в раздел uses модуль IdAllFTPListParsers, и отключив свойство TIdFTP.UseMLIS. Однако, это решение может привести к некорректному парсингу некоторых списков файлов, так как Indy не может распознать все существующие форматы списков.
Пример кода
Вот пример кода, который Demonstrates how to use the TIdFTP.List method correctly:
procedure TForm1.GetFileList(const Mask: string);
var
i: Integer;
begin
if not FTP.Connected then
FTP.Connect;
if (FTP.CanUseMLS) and (FTP.UseMLIS) then
FTP.List('', True)
else
FTP.List(Mask, False);
for i := 0 to FTP.DirectoryListing.Count - 1 do
begin
// Process directory items here.
end;
end;
В этом примере метод GetFileList принимает в качестве параметра маску файлов и вызывает метод TIdFTP.List с соответствующими параметрами в зависимости от поддержки сервером команды MLSD и значений свойств TIdFTP.UseMLIS и TIdFTP.CanUseMLS. После получения списка файлов пользователь может обработать его в цикле.
Статья описывает проблему с некорректным получением списка файлов на FTP-сервере с помощью компонента Indy FTP в Delphi и предлагает решение, основанное на правильном использовании метода TIdFTP.List и учете типа команд, отправляемых на сервер.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.