Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Удаление папки с файлами, idFTP


Автор: naPz 5.1.2007, 22:16
Хочу удалить в idFTP клиенте выделеную папку и всё что внутри если она не пустая. Стандартно зделать как я понял нельзя, поэтому удаляю вот такой процедурой с рекурсивным вызовом самой себя:

Код

procedure TForm1.DeleteDirectory(Dir: String);
var
  DL: TStringList;
  i: integer;
begin
    DL:=TStringList.Create;
    idFTP1.ChangeDir(Dir);
    idFTP1.List(DL);

    i:=0;
    while i <= idFTP1.DirectoryListing.Count-1 do
          begin
               if idFTP1.DirectoryListing[i].ItemType = ditDirectory then
                  begin
                       if (idFTP1.DirectoryListing[i].FileName <> '.') and (idFTP1.DirectoryListing[i].FileName <> '..')   then
                          begin
                               DeleteDirectory(idFTP1.DirectoryListing[i].FileName);
                               i:=0;
                               DL.Clear;
                               idFTP1.List(DL);
                          end
                  end
               else
                   idFTP1.Delete(idFTP1.DirectoryListing[i].FileName);
               inc(i);
          end;

    idFTP1.ChangeDir('..'); //  idFTP1.ChangeDirUp вылетает с ошибкой
    idFTP1.RemoveDir(Dir);
    DL.Free;
end;


Так если пройти эту процедуру в пошаговом режиме (F7,F8), то работает идеально и никаких глюков и ошибок нету. Удаляет все папки и файлы внутри выбраной папки.

Но если запустить в нормальном режиме то ничего не делает, если войти сразу после этого в папку которую хотел удалить вылетает с ошибкой EListError "List index out of bounds(тут число)".
Что-то с индексами. Переписывал по разному и никак не могу заставить работать.

Использую
Delphi 7 + Indy 9

....

Автор: bozhe 11.10.2008, 14:13
Вот работающий код. 

Код

procedure TNewsForm.DelFTPDir(Dir: String);
var DL: TStringList;
    L,FTPDL:TStringList;
    i: integer;
begin
  Application.ProcessMessages;
  if FTP.Connected then
  begin
    DL:=TStringList.Create;
    L:=TStringList.Create;
    FTPDL:=TStringList.Create;

    FTP.ChangeDir(Dir);
    FTP.List(DL);
    for i:=0 to DL.Count-1 do
    begin
      FTPDL.Add(FTP.DirectoryListing[i].FileName);
      if FTP.DirectoryListing[i].ItemType = ditDirectory then
      L.Add('d') else
      L.Add('f');
    end;

    for i:=DL.Count-1 downto 0 do
    begin
        if (L[i]='d') then
          begin
            if (FTPDL[i]<> '.') and
               (FTPDL[i]<> '..') then
                  begin
                   DelFTPDir(FTPDL[i]);
                  end;
          end
        else
          begin
           FTP.Delete(FTPDL[i]);
          end;
    end;
    FTP.ChangeDirUp;
    FTP.RemoveDir(Dir);
    FTPDL.Destroy;
    DL.Destroy;
    L.Destroy;
  end;
end;


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

FTP это тот же idFTP1 )

Автор: bankir 25.3.2009, 18:13
немножко переработанный код который действительно заработал (не претендует на оригинальность)
просто сам долго искал готовый код, может кому пригодится

Код

procedure TForm1.DelFTPDir(Dir: String);
var 
  DL: TStringList;
  i: integer;
begin
    DL:=TStringList.Create;

    FTP.ChangeDir(Dir);
    FTP.List(DL, '', false);

    for i:=0 to DL.Count-1 do
      begin
        if ftp.Size(dl.Strings[i])=-1 then
            DelFTPDir(dl.Strings[i]) //Рекурсия
        else
            FTP.Delete(dl.Strings[i]); //иначе удаляем файл
      end;
    FTP.ChangeDirUp;
    FTP.RemoveDir(Dir);
    DL.Free;
end;



Автор: ikot 3.7.2009, 03:25
Цитата(bankir @ 25.3.2009,  18:13)
немножко переработанный код который действительно заработал (не претендует на оригинальность)
просто сам долго искал готовый код, может кому пригодится

Код

procedure TForm1.DelFTPDir(Dir: String);
var 
  DL: TStringList;
  i: integer;
begin
    DL:=TStringList.Create;

    FTP.ChangeDir(Dir);
    FTP.List(DL, '', false);

    for i:=0 to DL.Count-1 do
      begin
        if ftp.Size(dl.Strings[i])=-1 then
            DelFTPDir(dl.Strings[i]) //Рекурсия
        else
            FTP.Delete(dl.Strings[i]); //иначе удаляем файл
      end;
    FTP.ChangeDirUp;
    FTP.RemoveDir(Dir);
    DL.Free;
end;

А как выглядит код сервера? 
А то у меня не выходит удалить непустую папку, используя ваш код. На сервере у меня код, приведенный в demo от indy. Я так понял, что он у вас другой... Какой, если не секрет?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)