Загрузка каталога с FTP-сервера

Я разрабатываю FTP-клиент с помощью RAD Studio (IdFTP). Как я могу загрузить каталог с сервера? Делфи или С++. Спасибо.


person Pavel Rabinovych    schedule 18.04.2014    source источник
comment
Что вы пробовали, что не удалось? Поиск в Google списка каталогов idftp дает вам достаточно для начала.   -  person Jan Doggen    schedule 18.04.2014
comment
Я могу получить список. Но мне нужно скачать папки с файлами. Процедура get() - загрузить файл с сервера. Я не понимаю, как скачать все файлы. Папка может содержать другие папки и файлы...   -  person Pavel Rabinovych    schedule 18.04.2014
comment
Это повторяющийся get() при обходе каталогов. Погуглите, начните строить, разместите здесь свой код, если он не работает.   -  person Jan Doggen    schedule 18.04.2014
comment
Возможный дубликат stackoverflow .com/questions/18745994/   -  person Graymatter    schedule 18.04.2014


Ответы (2)


Вам нужно вызвать TIdFTP.ChangeDir(), чтобы перейти к нужному начальному каталогу, затем вызвать TIdFTP.List(), чтобы получить имена его файлов и подкаталогов, затем выполнить цикл через TIdFTP.DirectoryListing, вызывающий TIdFTP.Get() для каждого имени файла, и сохранить имя каждого подкаталога в свой собственный локальный список, затем, наконец, повторить вышеуказанные шаги для каждого подкаталога в вашем локальном списке.

Например:

Procedure DownloadFolder(ARemoteFolder, ALocalFolder: string);
Var
  SubFolders: TStringList;
  I: Integer;
Begin
  ALocalFolder := IncludeTrailingPathDelimiter(ALocalFolder);
  ForceDirectories(ALocalFolder);
  SubFolders := TStringList.Create;
  Try
    FTP.ChangeDir(ARemoteFolder);
    FTP.List;
    For I := 0 to FTP.DirectoryListing.Count-1 do
    Begin
      If FTP.DirectoryListing[I].ItemType = ditFile then
      Begin
        FTP.Get(FTP.DirectoryListing[I].FileName, ALocalFolder + FTP.DirectoryListing[I].FileName);
      End
      Else if FTP.DirectoryListing[I].ItemType = ditDirectory then
      Begin
        if (FTP.DirectoryListing[I].FileName <> '.') and FTP.DirectoryListing[I].FileName <> '..') then
          SubFolders.Add(FTP.DirectoryListing[I].FileName);
      End;     
    End;
    For I := 0 to SubFolders.Count-1 do
    Begin
      DownloadFolder(ARemoteFolder + '/' + SubFolders[I], ALocalFolder + SubFolders[I]);
    End;
  Finally
    SubFolders.Free;
  End;
End;

DownloadFolder('/StartingDir', 'C:\Downloaded');
person Remy Lebeau    schedule 18.04.2014
comment
Спасибо. Я понимаю, что должна быть рекурсия. Не могли бы вы показать мне, как я могу обойти все каталоги и подкаталоги? - person Pavel Rabinovych; 20.04.2014
comment
Я добавил пример в свой ответ. Может потребоваться некоторая настройка, но это даст вам суть. - person Remy Lebeau; 20.04.2014

Необходимо добавить условие:

В противном случае, если ((IdFTP.DirectoryListing[I].ItemType = ditDirectory) и (Length(IdFTP.DirectoryListing[I].FileName) > 2)), то

чтобы избежать «..» в качестве имени каталога

person ShirleyCC    schedule 14.11.2017
comment
Неправильно полагаться на длину, так как могут быть настоящие папки, содержащие всего 1-2 символа. Чтобы проигнорировать элемент "..", проверьте его конкретно, и на всякий случай найдите также ".", например: Else if ((IdFTP.DirectoryListing[I].ItemType = ditDirectory) and (IdFTP.DirectoryListing[I].FileName <> '.') and (IdFTP.DirectoryListing[I].FileName <> '..')) then - person Remy Lebeau; 06.03.2020