Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Problem: Verzeichnis rekursiv einlesen


schlumsch - Di 15.12.09 22:47
Titel: Problem: Verzeichnis rekursiv einlesen
Hallo,

ich versuche Verzeichnisse rekursiv einzulesen und habe soeben benmerkt, das dabei eirgend etwas total schief läuft. Mein Verzeichnis hat 2 Unterverzeichnisse, in der Ergebnismenge tauchen diese jedoch immer doppelt auf. Zuerst werden beide Unterverzeichnisse einzeln nacheinander gefunden und dann am Ende noch einmal beide zusammen... ich sehe den Fehler allerdings nicht. Kann mir da jemand helfen, wäre schön wenn ihr euch mal meinen Code anschauen würdet:

Beispiel:
Die Ausgabe sieht zum Beispiel so aus:
0verzeichnisse
1verzeichnisse
data
2verzeichnisse
data
test

... was ich nicht raffe ist die Tatsache, das die Textausgaben "x verzeichnisse" eigentlich am Ende meiner Funktion stehen und dementsprechend auch nur einmal angezeigt werden sollten... was sie ja nun nicht tun...


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:
function dirToGlobalLists(Verzeichnis:string):longint;
var SR      : TSearchRec;
    Groesse : longint;
begin
  Groesse:=0;
  if Verzeichnis[length(Verzeichnis)]<>'\' then
    Verzeichnis:=Verzeichnis+'\';
  if FindFirst(Verzeichnis+'*.*',$3F,SR)=0 then begin
    repeat
      if ((SR.Attr and faDirectory)>0and (SR.Name<>'.'and (SR.Name<>'..'then
        Groesse:=Groesse+dirToGlobalLists(Verzeichnis+SR.Name)
      else
        Groesse:=Groesse+SR.Size;
      if (SR.Name<>'.'and (SR.Name<>'..')  then begin
          if isPicture(SR.Name) then begin
            FormDirectorySelect.MemoLog.Lines.Add('BILD: ' + SR.Name);
            DirsAndFiles.Add(Verzeichnis+SR.Name);
            pictureCount := pictureCount + 1;
          end else begin
          FormDirectorySelect.MemoLog.Lines.Add('KEIN BILD: ' + SR.Name);
            if directoryexists(SR.Name) then
              DirsOnly.Add(SR.Name);
          end;
        end;
    until FindNext(SR)<>0;
    FindClose(SR);
  end;

  FormDirectorySelect.ListBoxAllFiles.Items.Add(inttostr(DirsAndFiles.Count) + 'Bilder');
  FormDirectorySelect.ListBoxAllFiles.Items.AddStrings(DirsAndFiles);
  FormDirectorySelect.ListBoxDirectoriesOnly.Items.Add(inttostr(DirsOnly.Count) + 'Verzeichnisse');
  FormDirectorySelect.ListBoxDirectoriesOnly.Items.AddStrings(DirsOnly);
//   DirsAndFiles.Assign(FormDirectorySelect.ListBoxAllFiles.Items);
//  DirsAndFiles.Assign(FormDirectorySelect.ListBoxAllFiles);




  //  FormDirectorySelect.ListBoxAllFiles.Assign(DirsAndFiles);
  Result:=Groesse;
end;


Bergmann89 - Mi 16.12.09 00:02

Hey,

das "x Verzeichnisse" kommt mehrmals, weil du die Funktion ja auch mehrmals aufruft:

Delphi-Quelltext
1:
2:
3:
4:
if ((SR.Attr and faDirectory)>0and (SR.Name<>'.'and (SR.Name<>'..'then
  Groesse:=Groesse+dirToGlobalLists(Verzeichnis+SR.Name)
else
  Groesse:=Groesse+SR.Size;


Ich hab noch nich ganz verstanden was du machen willst. Du willst praktisch einmal nur die Verzeichnisse und einmal die Bilder und Verzeichnisse in Listen schreiben, oder?

MfG Bergmann


schlumsch - Mi 16.12.09 00:12

Ja ok das sehe ich ein, aber dennoch muss da ein Fehler in meinem Code sein. Ich will ja alle Unterverzeichnisse einlesen und muss dementsprechend meine Funktion rekursiv aufrufen


Bergmann89 - Mi 16.12.09 00:29

Hey,

was macht der Fehler denn, bzw. was passiert (nicht)? Wenn er dir mehrmals sagt wieviel Verzeichnesse es sind, dann läuft die Rekursion ja richtig...
So listet er mir alle Datein und Ordner der Reihe nach auf, vlt hilft dir das weiter:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure GetDir(Path: String; List: TStrings);
var Found: Integer;
var SearchRec: TSearchrec;
begin
  if Path[Length(Path)] <> '\' then Path := Path + '\';
  Found := FindFirst(Path+'*.*', faAnyFile, SearchRec);
  while Found = 0 do begin
    if (Searchrec.Name <> '.'and (Searchrec.Name <> '..'then
      begin
        List.Add(Path+SearchRec.Name);
        if DirectoryExists(Path+SearchRec.Name) then
          GetDir(Path+SearchRec.Name, List);
      end;
    Found := FindNext(SearchRec);
  end;
  FindClose(SearchRec);
end;


MfG Bergmann.


schlumsch - Mi 16.12.09 01:13

Nun, er listet mir eben auch meine Files jeweils doppelt auf, sprich meine Stringlisten enthalten am Ende jedes File 2mal, gemäß dem oben angeführten Directorylisting. Ich werde deine Procedur morgen mal probieren wenn ich von Arbeit komme... soweit schon einmal danke. Vielleicht sieht ja doch wer den Fehler den ich gemacht habe...


jaenicke - Mi 16.12.09 03:02

Warum prüfst du eigentlich weiter unten mit DirectoryExists ob es ein Verzeichnis ist? :autsch:
Oben hast du es doch schon über das Attribut faDirectory abgefragt, damit kannst du das doch direkt abfragen... Und so hast du es ja oben auch schon selbst kopiert und leider nicht angeschaut oder verstanden geschrieben... :mrgreen:

user profile iconschlumsch hat folgendes geschrieben Zum zitierten Posting springen:
... was ich nicht raffe ist die Tatsache, das die Textausgaben "x verzeichnisse" eigentlich am Ende meiner Funktion stehen und dementsprechend auch nur einmal angezeigt werden sollten... was sie ja nun nicht tun...
Einmal am Ende jedes Aufrufs, du rufst die Funktion aber ja rekursiv immer wieder auf.


schlumsch - Mi 16.12.09 11:01

Ich habe gestern die Funktion isPicture neu implementiert und in diese Prozedur eingefügt. Als ergebnis bakam ich dan in meine Stringlist Dirsonly alle Dateien, die keine Bilder sind, also exen, pas etc... Mein DirsOnly bestand also aus den Untervberzeichnissen (doppelt) und allen Dateien in diesen welche keine Bilder sind.


schlumsch - Mi 16.12.09 21:03

Oh mann, manchmal sieht man echt den Wald vor lauter Bäumen nicht... mein Code funktioniert wunderbar, nur sollte ich die paar Zeilen ganz am Ende nicht mit in die Rekursion packen... das hilft! :autsch: :autsch: :puke: