Autor Beitrag
DorJo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 139



BeitragVerfasst: Do 30.04.09 03:41 
Hy @ all,
ich hab mal wieder ein Problem :(

Ich wollte gern eine Funktion schreiben, mit der ich ein Backup von einem FTP Server ziehen kann! Das is mein Quelltext:
ausblenden volle Höhe 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:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
function TForm1.Backupunderdir(): boolean;
var str,ftpDir, TargetFile: string;
    a,b,c: integer;
    richtig,result: boolean;
begin
  result:=false;
  SetLength(dirarray_str,0);
  for a := 0 to Listview1.Items.Count-1 do
  begin
    if (Listview1.Items.Item[a].SubItems.IndexOf('DIR')<>-1then
    begin
      SetLength(dirarray_str,Length(dirarray_str)+1);
      dirarray_str[Length(dirarray_str)-1]:=Listview1.Items.Item[a].Caption;
    end
    else
    begin
      if Listbox4.Items.Count>0 then
        ftpDir:='/'+listbox4.Items.Strings[listbox4.Items.Count-1]+'/'
      else ftpDir:='/';
      TargetFile:=Label17.Caption+Listview1.Items.Item[a].Caption+'.'+Listview1.Items.Item[a].SubItems.strings[0];
      (FtpDownloadFile(server_adresse, benutzername, passwort, 21, ftpDir, Listview1.Items.Item[a].Caption+'.'+Listview1.Items.Item[a].SubItems.strings[0], TargetFile, ProgressBar1));
    end;
  end;
  if Length(dirarray_str)>0 then
  begin
    for c := 0 to Length(dirarray_str)-1 do
    begin
      TargetFile:=Label17.Caption+dirarray_str[c];
      CreateDir(TargetFile);
      //Label17.Caption:=TargetFile;
      Listbox4.Items.Add(dirarray_str[c]);
      ShowMessage(dirarray_str[c]);
      IdFTP1.ChangeDir(dirarray_str[c]);
      Listbox5.Clear;
      IdFTp1.Status(Listbox5.items);
      Listbox1.Items.AddStrings(Listbox5.Items);
      if IdFTP1.connected then
      begin
        Listbox2.Clear;
        Listbox3.Clear;
        Listview1.Clear;
        IdFTP1.list(listbox2.items);
        for b := 0 to Listbox2.Count - 1 do
        begin
          str:=Listbox2.Items.Strings[b];
          for a:=length(str) downto 1  do
          begin
            if (str[a]='.'then
            begin
              richtig:=false;
              break;
            end
            else if (str[a]<>' 'then
            begin
              richtig:=true;
            end;
            if richtig=true then
            begin
              richtig:=false;
              Listbox3.items.add(str);
              break;
            end;
          end;
        end;
        FTPsort();
      end;
      Backupunderdir();
    end;
  end
  else result:=true;
end;


Die Überlegung ist folgende:
Alle Dateien/Ordner werden in einem Listview angezeigt. Die Funktion soll nun nichts weiter machen als alle Einträge in der Listview durchgehen, alle Dateien downloaden und anschließend in die Ordner wechseln und dann alles von vorne bis alle Ordner vollständig durchlaufen und gedownloadet sind.

Nur leider funktioniert die rekursive Programmierung nicht so wie ich es gelernt hab :( entweder mach ich was falsch, oder die Sache mit den Stacks funktioniert nicht so ganz. Nach dem ersten Ordner tritt nämlich eine Exception auf :(

Kann mir da jemand helfen? Kennt vielleicht jemand einen besseren Weg?

Ich danke schonmal im Voraus!

MfG

DorJO
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 30.04.09 04:31 
Durch die Vermischung der Oberflächenkomponenten und der Funktion wird das extrem unübersichtlich.

Wozu brauchst du die ListBoxen zum Beispiel? Du löschst die doch ohnehin immer wieder. Soll das sein, damit der Benutzer sieht, dass da was passiert? :gruebel:

Vor allem solltest du das hinein- und wieder hinauswechseln innerhalb des rekursiven Aufrufs machen und nicht vorher, dann wird das etwas übersichtlicher.
DorJo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 139



BeitragVerfasst: Do 30.04.09 05:30 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Durch die Vermischung der Oberflächenkomponenten und der Funktion wird das extrem unübersichtlich.

Wozu brauchst du die ListBoxen zum Beispiel? Du löschst die doch ohnehin immer wieder. Soll das sein, damit der Benutzer sieht, dass da was passiert? :gruebel:


Tut mir echt leid. Hast schon Recht, der Code is relativ unübersichtlich, weil schon eher älter :(

Nun zur Erklärung:
In der Funktion FTPSort() wird die Listview gefüllt mit dem Inhalt des Ordners auf dem Server. Dabei wird (zur Hilfe) in die Listbox4 der momentane Ordner geschrieben, sodass folgende Struktur entsteht:
Auf Server:
Ordner1
|--> Ordner3
|--> Ordner4
||--> Ordner5
Ordner2

In Listview4, wenn er im tiefsten Ordner angelangt ist:
Ordner1
Ordner4
Ordner5

ListBox3 zeigt dem User an, oder besser gesagt "soll anzeigen", was grad passiert.
ListBox2 enthält die gesamten Dateien des Ordners vom Server


Was ich mal fragen wollte, gibt es vielleicht so eine hübsche Funktion wie FindFirst, FindNext... für die IdFTP Kompo? weil dazu hab ich nichts gefunden :( Aber wenn dann würde das das ganze Prozedere unglaublich vereinfachen können! Oder habt ihr vielleicht irgendeine (vielleicht) noch bessere Idee für das Problem?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 30.04.09 14:39 
Dir ist schon klar, dass du das auch ohne die visuellen Komponenten auslesen kannst, oder?

Wenn du das dann sauber umsetzt, z.B. mit einer einfachen TStringList, dann ginge das viel besser.
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Do 30.04.09 15:23 
Wie jaennicke schon sagte kannst du den Verzeichnisinhalt auch direkt in eine StringList schreiben, und musst ihn dir nicht in einer ListBox o.ä. anzeigen lassen um ihn von dort aus weiter zu verarbeiten.

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
DorJo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 139



BeitragVerfasst: Sa 09.05.09 14:38 
Zitat:
Wie jaennicke schon sagte kannst du den Verzeichnisinhalt auch direkt in eine StringList schreiben, und musst ihn dir nicht in einer ListBox o.ä. anzeigen lassen um ihn von dort aus weiter zu verarbeiten.


Ja das kann schon stimmen, aber ist das denn so schlimm, wenn ich es anders mache? Das klingt jetzt vielleicht komisch, aber wie kann ich denn dieses Problem mit einer StringList lösen? Ich hab da jetz grad ein Brett vorm Kopf :(
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 09.05.09 15:55 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
// statt
IdFTp1.Status(Listbox5.items);
// einfach
IdFTp1.Status(DeineStringList);
Und schon missbrauchst du nicht mehr die visuelle Komponente...

Erzeugen musst du die StringList natürlich vorher. Dann aber kannst du auch mehrere parallel verwenden, was bei der ListBox ja nicht geht und daher in der Rekursion zu Problemen führt...