Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Unterordner und deren unterordner (https://www.delphipraxis.net/142647-unterordner-und-deren-unterordner.html)

gangs-taas 31. Okt 2009 23:10


Unterordner und deren unterordner
 
Hey,
wüsstet ihr eine möglichkeit in einem Ordner nach unterordern zu suchen und falls in diesen unterordnern auch unterorder sind diese auch ect. ?
also allgemein unterordner suchen geht ja leicht mit FindFirst ect.
aber ich bin planlos wie ich es hinbekommen kann beleibig viele ebenen zu durchsuchen ...

also er soll halt alle ebenen in diesem ordner durchsuchen bis es keine mehr gib ....

wüsstet ihr wie das möglich wäre ? :)

danke schonmal :)

Matze 31. Okt 2009 23:11

Re: Unterordner und deren unterordner
 
Hallo,

dafür ist die Rekursion wie geschaffen (eine Funktion ruft sich selbst wieder auf). Schaue mal nach FindAllFilesFindAllFiles. Intern wird wieder FindFirst/FindNext benutzt.

Grüße, Matze

gangs-taas 31. Okt 2009 23:22

Re: Unterordner und deren unterordner
 
ich bin zu dämlich um zu verstehn wie das funst :D :D

Matze 31. Okt 2009 23:34

Re: Unterordner und deren unterordner
 
Die Rekursion ist auch nicht ganz einfach. Wenn man sie jedoch verstanden hat, lassen sich damit viele Dinge mit sehr wenig Code lösen (Türme von Hanoi, Berechnung der Fakultät, ...). Sie kommt meist dort zum Einsatz, wo man von vornherein keine direkte Abbruchbedingung für eine Schleife angeben kann (die Anzahl der Unterordner ist vorerst unbekannt). Mit Schleifen geht es sicher auch, nur deutlich komplizierter.

Ganz grob mal wie's geht, aber um es genau zu verstehen müsstest du auch die internen Abläufe wissen. Vielleicht findest du bei Wikipedia eine entsprechende Erklärung.

Die CL-Funktionen erwarten als Parameter das Verzeichnis, in dem gesucht werden soll. Dann beginnt die Funktion per FindFirst/FindNext nach einem Unterordner zu suchen. Wurde einer gefunden, ruft sich die Funktion selbst wieder auf mit dem Unterordner als Parameter. Für den neuen Funktionsaufruf ist das aktuelle Verzeichnis somit der Unterordner. Dann wird darin nach dem "Unter-Unterordner" gesucht etc. pp.

Jedes Mal, wenn sich die Funktion selbst wieder aufruft, wird die Funktion ihren weiteren Ablauf unterbrechen. Das was nach dem rekursiven Aufruf an Code folgt, muss jedoch irgendwann auch abgearbeitet werden und das erfolgt nach allen rekursiven Aufrufen (letzter Unterordner) rückwärts, da das ganze so auf dem Stack abgelegt ist (First in, Last out, wenn man so will).
Naja es ist kompliziert und das eben so zu erklären kann ich nicht wirklich. Ich hoffe in der Beschreibung keinen Fehler gemacht zu haben (es ist schon spät).
Da solltest du dich ggf. mit anderen Quellen näher beschäftigen, um das wirklich zu verstehen. ;)

Grüße, Matze

himitsu 31. Okt 2009 23:43

Re: Unterordner und deren unterordner
 
Matze meinte ja ich solle mein "Wissen" teilen :lol:

ohne Recursion würde es z.B. auch so gehn :angel2:

- ein Verzeichnis kann maximal MAX_PATH lang sein
(inklusive abschließender PChar-#0 und der Laufwerkskennung)
- macht also 255 Zeichen für den Pfad
- ein Pfad kann mindestens 1 Zeichen lang sein
- macht sozusagen 255/2 = maximal 127 Verzeichnisebenen

bedeutet du müßtest 127 Leseschleifen verschachteln :nerd:

Hier mal der gekürzte Code ... für die ersten 3 und die letzte Schleife
(die restlichen 123 Schleifen müßte man also NUR noch einfügen und durchnummerieren)
Delphi-Quellcode:
Procedure FindAllFilesWithoutRekursion(Dir: String; SL: TStrings);
  Var R1, R2, R3, R4, R5 ... R127: TSearchRec;
    D2, D3, D4, D5 ... D127: String;

  Begin
    Dir := IncludeTrailingPathDelimiter(Dir);
    If FindFirst(Dir + '*.*', R1) = 0 Then Begin
      Repeat
        If (R1.Name = '.') or (R1.Name = '..') Then Continue;
        If R1.Attr and faDirectory <> 0 Then Begin

          D2 := Dir + R1.Name + '\';
          If FindFirst(D2 + '*.*', R2) = 0 Then Begin
            Repeat
              If (R2.Name = '.') or (R2.Name = '..') Then Continue;
              If R2.Attr and faDirectory <> 0 Then Begin

                D3 := D2 + R2.Name + '\';
                If FindFirst(D3 + '*.*', R3) = 0 Then Begin
                  Repeat
                    If (R3.Name = '.') or (R3.Name = '..') Then Continue;
                    If R3.Attr and faDirectory <> 0 Then Begin

                      ...

                      D127 := D126 + R126.Name + '\';
                      If FindFirst(D127 + '*.*', R127) = 0 Then Begin
                        Repeat
                          If (R127.Name = '.') or (R127.Name = '..') Then Continue;
                          If R127.Attr and faDirectory <> 0 Then
                            Raise Exception.Create('zuviele Verzeichnisse gefunden');
                          Else SL.Add(D127 + R127.Name);
                        Until FindNext(R127) <> 0;
                        FindClose(R127);
                      End;

                      ...

                    End Else SL.Add(D3 + R3.Name);
                  Until FindNext(R3) <> 0;
                  FindClose(R3);
                End;

              End Else SL.Add(D2 + R2.Name);
            Until FindNext(R2) <> 0;
            FindClose(R2);
          End;

        End Else SL.Add(Dir + R1.Name);
      Until FindNext(R1) <> 0;
      FindClose(R1);
    End;
  End;
also ganz im Ernst ... lerne lieber das mit der Rekursion :angel:


PS: wenn man sich den Code so ansieht, dann kann man das ganze auch ganz schön via Interation lösen :)

waub 1. Nov 2009 00:02

Re: Unterordner und deren unterordner
 
Möglicherweise ist der folgende Beitrag hilfreich:
Rekursive Suche

Lannes 1. Nov 2009 00:22

Re: Unterordner und deren unterordner
 
Hallo,
Zitat:

Zitat von himitsu
...
PS: wenn man sich den Code so ansieht, dann kann man das ganze auch ganz schön via Interation lösen :)

ja, und das mit nur einer Schleife die solange läuft bis in der Ordner-Sammel-Stringliste das Ende erreicht ist. :wink:
Hab das mal ausgetestet, ist auch nur geringfügig langsamer als die rekursive Lösung.

gangs-taas 1. Nov 2009 08:51

Re: Unterordner und deren unterordner
 
Zitat:

Zitat von Matze
Die Rekursion ist auch nicht ganz einfach. Wenn man sie jedoch verstanden hat, lassen sich damit viele Dinge mit sehr wenig Code lösen (Türme von Hanoi, Berechnung der Fakultät, ...). Sie kommt meist dort zum Einsatz, wo man von vornherein keine direkte Abbruchbedingung für eine Schleife angeben kann (die Anzahl der Unterordner ist vorerst unbekannt). Mit Schleifen geht es sicher auch, nur deutlich komplizierter.

Ganz grob mal wie's geht, aber um es genau zu verstehen müsstest du auch die internen Abläufe wissen. Vielleicht findest du bei Wikipedia eine entsprechende Erklärung.

Die CL-Funktionen erwarten als Parameter das Verzeichnis, in dem gesucht werden soll. Dann beginnt die Funktion per FindFirst/FindNext nach einem Unterordner zu suchen. Wurde einer gefunden, ruft sich die Funktion selbst wieder auf mit dem Unterordner als Parameter. Für den neuen Funktionsaufruf ist das aktuelle Verzeichnis somit der Unterordner. Dann wird darin nach dem "Unter-Unterordner" gesucht etc. pp.

Jedes Mal, wenn sich die Funktion selbst wieder aufruft, wird die Funktion ihren weiteren Ablauf unterbrechen. Das was nach dem rekursiven Aufruf an Code folgt, muss jedoch irgendwann auch abgearbeitet werden und das erfolgt nach allen rekursiven Aufrufen (letzter Unterordner) rückwärts, da das ganze so auf dem Stack abgelegt ist (First in, Last out, wenn man so will).
Naja es ist kompliziert und das eben so zu erklären kann ich nicht wirklich. Ich hoffe in der Beschreibung keinen Fehler gemacht zu haben (es ist schon spät).
Da solltest du dich ggf. mit anderen Quellen näher beschäftigen, um das wirklich zu verstehen. ;)

Grüße, Matze

vielen dank erst einmal dafür hat mir echt geholfen das system zu verstehen :)
ich hab noch eine frage dazu
wenn du z.b. die Fakulät mit einer Reursion lösen möchte...
woher weiß das programm denn dann wann es aufhören muss sich selbst aufzurufen ?

Matze 1. Nov 2009 08:54

Re: Unterordner und deren unterordner
 
Du musst eine entsprechende Abbruchbedingung definieren:

Delphi-Quellcode:
function fak_rek(n: Integer): Integer;
begin
  if n <= 1 then // Abbruchbedingung
    Result := 1
  else
    Result := n * fak_rek(n-1);
end;

gangs-taas 1. Nov 2009 09:01

Re: Unterordner und deren unterordner
 
hm.. okay :)
jetzt muss ich nur noch versuchen, dass auf mein problem zu übertragen :)
das hier :
Zitat:

Zitat von waub
Möglicherweise ist der folgende Beitrag hilfreich:
Rekursive Suche

hab ich mir zwar angeguckt ich will das aber eigl. nicht einfach übernehmen, sondern es so nachvollziehen, das ich das auch ohne copy&past schreiben kann :)

danke für eure hilfe !!

Matze 1. Nov 2009 09:09

Re: Unterordner und deren unterordner
 
In dem von "waub" verlinkten Thema (das über meinen Link auch aufgelistet wird) ist auch die Abbruchbedingung vorhanden. Das muss bei der Rekursion auch immer so sein, sonst ruft sich die Funktion so lange auf, bis es Speicherprobleme gibt.

Delphi-Quellcode:
if SR.Attr and faDirectory = faDirectory then         // Verzeichnis wurde gefunden
  if (SR.Name <> '.') and (SR.Name <> '..') then      // Verzeichnis ist nicht das aktuelle "." und nicht das übergeordnete ".." Verzeichnis
    FindAllFiles(RootFolder + SR.Name, Mask, Recurse); // rekusriver Aufruf
Die Funktion ruft sich somit nur dann selbst wieder auf, wenn ein Unterverzeichnis gefunden wurde.

Übrigens finde ich deine Einstellung super. :thumb: Das ist bei weitem nicht selbstverständlich.
Es gibt hier welche, die wollen fertige Lösungen und diese ohne nachzudenken per Copy&Paste übernehmen. Und dann kommen ständig Fragen, wieso dies und jenes nicht funktioniert, wie man den Code ändern muss etc. Deine Einstellung sollten alle haben. Du lernst dadurch viel und kannst später auch selbst Probleme lösen. So macht es Spaß und da helfe ich dann auch gerne.

Grüße, Matze

gangs-taas 1. Nov 2009 09:13

Re: Unterordner und deren unterordner
 
Zitat:

Zitat von Matze
Übrigens finde ich deine Einstellung super. :thumb: Das ist bei weitem nicht selbstverständlich.
Es gibt hier welche, die wollen fertige Lösungen und diese ohne nachzudenken per Copy&Paste übernehmen. Und dann kommen ständig Fragen, wieso dies und jenes nicht funktioniert, wie man den Code ändern muss etc. Deine Einstellung sollten alle haben. Du lernst dadurch viel und kannst später auch selbst Probleme lösen. So macht es Spaß und da helfe ich dann auch gerne.

Grüße, Matze

Danke :) :oops: :oops:

Fridolin Walther 4. Nov 2009 23:40

Re: Unterordner und deren unterordner
 
Zitat:

Zitat von himitsu
- ein Verzeichnis kann maximal MAX_PATH lang sein
(inklusive abschließender PChar-#0 und der Laufwerkskennung)

Die Aussage ist falsch. Die maximale Pfadlänge bei NTFS beträgt 32767. Ich glaube sogar wir hatten die Unterhaltung schon mal als es um ein ähnlich angesiedeltes Thema ging.

himitsu 5. Nov 2009 01:10

Re: Unterordner und deren unterordner
 
das weiß ich schon, aber dieses betrifft nur UNC-Pfade und diese nutzt fast keiner...

es leben die alten DOS-Pfade :roll:

Fridolin Walther 5. Nov 2009 10:44

Re: Unterordner und deren unterordner
 
Zitat:

Zitat von himitsu
das weiß ich schon, aber dieses betrifft nur UNC-Pfade und diese nutzt fast keiner...

Es handelt sich dabei nicht um UNC Pfade. Der UNC Namespace in der Notation hätte den Prefix \\?\UNC\.

himitsu 5. Nov 2009 10:52

Re: Unterordner und deren unterordner
 
OK, es geht mit mindestens diesem \\.\X:\...
Bei X:\... geht es nur bis MAX_PATH und genau so machen es sehr viele auch.

Und es kommt wohl recht selten vor, daß vorallem Privatanwender mal 'ne größere Pfadtiefe bei sich vorliegen haben :stupid:

Fridolin Walther 5. Nov 2009 11:18

Re: Unterordner und deren unterordner
 
Zitat:

Zitat von himitsu
Und es kommt wohl recht selten vor, daß vorallem Privatanwender mal 'ne größere Pfadtiefe bei sich vorliegen haben :stupid:

Du hast recht, von sich aus benutzen Privatanwender so etwas wohl kaum. Es gibt aber einige Malware die diese Pfadtiefen ausnutzen, da es in der Tat immer noch Anti-Malware Software gibt, die nicht in der Lage ist den vollen Win32 Namespace zu scannen.

himitsu 5. Nov 2009 11:43

Re: Unterordner und deren unterordner
 
Liste der Anhänge anzeigen (Anzahl: 1)
ach was, da schmuggelt man einfach nur ein "böses" Zeichen in den Dateinamen und schon drehen noch mehr Programm durch
ein * macht sich da immer gut


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz