Entwickler-Ecke

Internet / Netzwerk - FTP Dir herunterladen mit sämtlichen unterordnern


the-kecks - So 24.01.10 00:03
Titel: FTP Dir herunterladen mit sämtlichen unterordnern
hi,
hab ein problem beim download von Dirs mit IdFTP.
Mein Code bisher:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
  try
    with IdFTP1 do
    begin
      DirListing := TStringList.Create;
      for i := 0 to DirectoryListing.Count - 1 do
      with DirectoryListing[i] do
      begin
        if ItemType <> ditDirectory then
        begin
          Application.ProcessMessages;
          Get(FileName, ExtractFilePath(ParamStr(0)) + ListBox1.Items[ListBox1.ItemIndex] + '\' + FileName, True, True);
        end
        else
          DirListing.Add(Filename);

        if DirListing.text<>'' then
        begin
          //gleiche wie oben mit for schleife: i:=0 to DirListing.Count-1
        end;
      end;
      ChangeDirUp;
    end;
  except;
  end;

Damit hab ich aber nur die Unterordner des vorher ausgewählten Ordners. Ich will aber auch die Unterordner der Unterordner usw.
Jmd eine Idee wie ich das hinkriegen könnte?

mfg


Delete - So 24.01.10 00:16

Du musst die Funktion rekursiv mit dem Unterverzeichnis aufrufen.


the-kecks - So 24.01.10 00:58

und wie? egal wie ich es mir überlege, ich komme nie auf die perfekte lösung (jeden unterordner rausfiltern)

mfg


jaenicke - So 24.01.10 01:02

Na, du hast eine Funktion, die dir den Inhalt eines Ordners herunterlädt. Und was muss bei den Unterordnern passieren? Das selbe.

Also musst du nur alle Unterordner durchgehen und für jeden Ordner wieder die selbe Funktion aufrufen. Diese lädt ja genau den Inhalt eines Ordners herunter.


the-kecks - So 24.01.10 01:08

ja das hatte ich mir auch überlegt.
aber dann kann ich ja nur auslesen
Dir\Dir1\Dir2\Dir3
was ist wenn in Dir1 aber 2 Unterordner sind?

mfg


jaenicke - So 24.01.10 01:36

Na, du machst das ja für jeden Unterordner, nicht nur für den ersten.

Beispiel:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Root
 |
  \-> Dir1
 |     |
 |      \-> Dir11
 |     |
 |      \-> Dir12
 |
  \-> Dir2
       |
        \-> Dir21
So, du rufst jetzt deine Funktion auf für Root. Diese kopiert daraufhin alle Dateien darin und geht dann alle Unterordner durch. Zuerst den ersten, Dir1.

Dort passiert wieder das gleiche, alle Dateien kopieren, alle Unterordner, in dem Fall Dir11 und Dir12 und damit die Dateien darin kopieren. Dort gibt es keine Unterordner, also kehren die Funktionen direkt wieder zurück.

Jetzt ist die Funktion, die Dir1 behandelt hat, auch beendet, da alle Dateien und Unterordner abgearbeitet sind. Also geht es in der ersten Funktion, die Root behandelt, weiter mit dem nächsten Unterordner, also Dir2. Darin wiederum mit Dir21.

Und damit sind dann alle Dateien und Verzeichnisse kopiert. Welche werden denn da deiner Meinung nach ausgelassen? :gruebel:


the-kecks - So 24.01.10 01:45

ich glaube ich hänge einfach bei diesem "netz".


Quelltext
1:
2:
3:
4:
5:
dir0 --> dir1--> dir3
                 dir4
         
         dir2--> dir5
                 dir6

usw.
dh es ist nicht ein "fluss" dir1 --> dir2 --> dir3 --> dir4 sondern ein netz das sich ausbreitet.

mfg


jaenicke - So 24.01.10 02:46

So ungefähr. Der Punkt ist einfach, dass durch die Rekursion die eine Aufgabe eben so lange hängt bis die jeweiligen Unteraufgaben der Reihe nach aufgerufen und abgearbeitet sind.


the-kecks - So 24.01.10 02:53

ja das system ist mir ja klar. aber wie fasse ich das in code?

mfg


jaenicke - So 24.01.10 03:12

Naja, wie schon gesagt...
Als Pseudocode:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure LoadFolder(AName: string);
begin
  ChangeDir(AName);
  LoadFiles;
  for SubDir in SubDirs do
    LoadFolder(SubDir);
  ChangeDirBack;
end;


the-kecks - So 24.01.10 17:05

erstmal: DANKE!
es funzt jetzt, ich brauche nurnoch eine funktion, die mir den kompletten pfad angibt in dem IdFTP sich gerade bewegt (also zb.: Root\Dir1\Dir2\Dir3), damit ich die entsprechenden unterordner erstellen kann.
//btw bei mir ist AWorkCountMax im ereignis OnWorkBegin immer 0, hab es mit IdFTP1.Size(Filename) versucht, da hängt sich das prog auf :(

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm9.IdFTP1WorkBegin(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCountMax: Int64);
begin
  if bDownloading=true then
  begin
    ProgressBar1.Max:=AWorkCountMax;
  end;
end;


mfg


jaenicke - So 24.01.10 22:58

Erstens: Wie wäre es mit RetrieveCurrentDir?
http://www.indyproject.org/docsite/html/frames.html?frmname=topic&frmfile=TIdFTP_RetrieveCurrentDir.html

Zweitens hast du noch einen Fehler drin, du vergleichst mit True, das kann böse ins Auge gehen [http://www.delphi-forum.de/viewtopic.php?p=548760#548760] und ist nicht gerade logisch [http://www.delphi-forum.de/viewtopic.php?p=560637#560637]...
Mehr dazu steht hier [http://www.delphi-treff.de/tutorials/objectpascal/programmierung-mit-boolean-werten/page/4/].
Deshalb einfach:

Delphi-Quelltext
1:
  if bDownloading then                    


the-kecks - So 24.01.10 23:57

erstens: danke, habe die ganze zeit nach was mit currentDir gesucht, aber das hab ich nicht gefunden.

Zweitens: sry, hab mir das als ich angefangen hab mit delphi so angewöhnt :/ muss mal versuchen mit das abzugewöhnen.
Es geht aber leider immernoch nicht. AWorkCountMax ist immer 0. Benutze die neuste Indy10 version, mit einer etwas älteren hat es noch geklappt (die alte version wieder drauf machen ist keine option für mich^^)
//Verbindung erofolgt via SFTP, mit normalem FTP klappt es auch mit der neuen version
habs so gelöst: ProgressBar1.Max:=IdFTP1.DirectoryListing[i].Size;

mfg