AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dateien, Unterverzeichnisse zählen?

Ein Thema von Mattze · begonnen am 12. Nov 2008 · letzter Beitrag vom 16. Okt 2009
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.139 Beiträge
 
Delphi 12 Athens
 
#11

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 20:01
Ich hoffe mal es läuft im Hauptthread, denn sonst wird wohl Application.ProcessMessages schuldig sein.

(im Normalfall wird es bei MAX_PATH nicht viel mehr als 30 Verzeichnisebenen geben ... aber egal)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
nat

Registriert seit: 10. Nov 2005
216 Beiträge
 
RAD-Studio 2009 Pro
 
#12

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 00:53
Zitat von 0xF30FC7:
Eigentlich kann alles was in einer rekursiven Funktion gelöst wird, auch in einer nicht-rekursiven Funktion gelöst werden. Im Falle von Verzeichnisenumerierung ist es sogar sinnvoll.
wie würde denn dann so ein simples verzeichnis-auflistung ohne rekursion aussehen? nur mal so aus interesse.
  Mit Zitat antworten Zitat
Mattze

Registriert seit: 6. Jan 2005
664 Beiträge
 
#13

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 10:15
Hallo,

da habe ich ja was angestellt...
Ich hätte nicht gedacht, dass das doch ein ziemliches Problem zu sein scheint!

Ich habe aus der Function nichts rausgekürzt. Die ist schon sehr alt und es kam mir von vornherein darauf an, dass die möglichst "universell" einsetzbar ist, also möglichst in sich abgeschlossen mit genau definierten Schnittstellen von und nach draußen.

In der Delphi-Umgebung kommt weiterhin der Fehler. ("In der Klasse TVirtualExplorerEasyListview ist folgender Fehler aufgetreten: Zugriffsschutzverletzung bei Adresse... Lesen von Adresse 00000004.")
(Ich habe mir zur Vereinfachung eine globale Fehlerbehandlung gebastelt, deshalb der Klassenname.)

Ich habe jetzt FGAbbruch zum Abbruch der Rekursion gesetzt. In der Delphi-Umgebung kommt der Fehler immer noch, starte ich es standalone, kommt der Fehler nicht mehr. Muss ich aber noch eine Weile probieren. Allerdings ist das natürlich auch keine Lösung!

Wann der Fehler auftritt:
Ich habe links eine Liste von Verzeichnissen. Rechts eine Art Betrachterfenster.
Wenn ich nun auf ein Verzeichnis clicke, wird rechts im Betrachter eine neue Form erzeugt. (Oder, wenn vorhanden, deren Inhalt geändert.) In dieser Form wird nur ein Listview erzeugt und darin ein paar Informationen zum Verzeichnis angezeigt. Dafür wird eben "Foldersize" auch berechnet.
Mache ich aber einen Doppelclick, gibt es den Fehler(, aber nicht immer).

Mal sehen, ob ich das im OnClick machen kann, wo ich auf dann den Doppelclick warte. (Bisher OnItemSelectedChanged - wer's kennt. Evtl. geht es nicht anders, weil sonst die Tastatursteuerung nicht funktioniert - also Taste hoch oder so. OnKeyUp oder OnKeyDown gibt es leider nicht.)

So, fehlt noch was?

Gruß
Mattze

PS: Der Stack müsste eigentlich ausreichen. Soooo tief ist das nicht. Vielleicht 3 höchstens 4 Stufen.
Das "Lesen von Adresse 00000004" deutet eher darauf hin, dass ein Pointer nicht richtig zugewiesen wurde. Da der Fehler nur unter Delphi, aber nicht standalone auftritt, könnte das ein Zeitproblem sein!? Aber, was tun?
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#14

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 11:02
Das würde in etwa so aussehen:

Delphi-Quellcode:
procedure EnumerateDirectory(Path : string);

  // Hilfsfunktion um aus dem Grundpfad und dem SearchRecord Array einen Pfad zu bilden
  function GetPath(Path : string; const SearchRecords : array of TSearchRec) : string;
  var
    i : Integer;
  begin
    Result := IncludeTrailingPathDelimiter(Path);
    for i := 0 to Length(SearchRecords) - 2 do
      Result := Result + SearchRecords[i].Name + '\';
  end;

var
  SearchRecords : array of TSearchRec;
  Index : Integer;
  ErrorCode : Integer;
begin
  SetLength(SearchRecords, 1);
  Index := 0;

  // So lang unser SearchRecords Array mindestens einen Eintrag hat, wird unsere Schleife ausgeführt ...
  while Index >= 0 do
    begin

      // Falls der derzeitige SearchRecord noch nicht initialisiert ist, tun wird dies mit FindFirst, ansonsten
      // wird FindNext benutzt um den nächsten Eintrag zu suchen
      if SearchRecords[Index].Name = ''
        then ErrorCode := FindFirst(GetPath(Path, SearchRecords) + '*.*', faAnyFile, SearchRecords[Index])
        else ErrorCode := FindNext(SearchRecords[Index]);

      while ErrorCode = 0 do
        begin
          // Falls das derzeitige Objekt kein Unterverzeichnis ist, geben wir es aus ...
          if SearchRecords[Index].Attr and faDirectory = 0
            then
              Writeln(GetPath(Path, SearchRecords) + SearchRecords[Index].Name)
            else
              // Falls es ein Unterverzeichnis ist und ungleich '.' oder '..' erweitern wir unser Array
              // und brechen die Schleife ab um von vorn zu beginnen
              if (SearchRecords[Index].Name <> '.') and (SearchRecords[Index].Name <> '..') then
                begin
                  SetLength(SearchRecords, Length(SearchRecords) + 1);
                  Index := Length(SearchRecords);
                  Break;
                end;
          ErrorCode := FindNext(SearchRecords[Index])
        end;

      Dec(Index);

      // Falls wir grade einen neuen SearchRecord in unser Array eingefügt haben ist
      // Index + 1 die Länge unseres Array. In dem Fall passiert also nichts.
      // Falls wir die Schleife normal durchlaufen haben und die Suche im derzeitigen Verzeichnis
      // somit beendet ist, ist Index + 1 die Länge des Arrays - 1. Entsprechend wird der letzte Record
      // im Array entfernt.
      SetLength(SearchRecords, Index + 1);
    end;
end;
Die Funktion ist kurz zusammengeschrieben. Ich habs zwar kurz auf Funktionstüchtigkeit getestet, allerdings übernehm ich keine Garantie das wirklich alles so funktioniert wie es soll bzw. das die generierte Dateiliste wirklich vollständig ist (will heißen ich hab den Output der Funktion nicht mit dem Output einer "normalen" rekursiven Funktion verglichen).

Prinzipiell wird in dem Falle der Stack durch ein Array simuliert. Sobald wir auf ein Unterverzeichnis stoßen, erzeugen wir einen neuen Eintrag im Array für unser Unterverzeichnis und brechen die derzeitige Schleife ab um im grade gefunden Unterverzeichnis nach Dateien zu suchen usw. usf.. Sobald ein (Unter-)Verzeichnis komplett durchsucht wurde, wird der letzte Record entfernt und die zuvor abgebrochene Schleife wieder aufgenommen. Das Ganze geschieht so lange, bis kein SearchRecord mehr im Array ist.
Fridolin Walther
  Mit Zitat antworten Zitat
Mattze

Registriert seit: 6. Jan 2005
664 Beiträge
 
#15

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 13:40
Hallo 0xF30FC7,

vielen Dank für die nichtrekursive Variante!
Ich habe es zwar bei mir noch nicht eingebaut, aber mit der rekursiven Variante von oben
verglichen. (Etwas aufgebohrt für das FG.)

Es ergibt das gleiche Ergebnis und ist sogar etwa 1,5 ms schneller als das rekursive. (Bei dem von mir überprüften Ordner!)

Gefällt mir sehr!!!

Gruß
Mattze
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#16

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 13:57
Das war eher ne Demonstration weil jemand gefragt hat wie man das Problem ohne Rekursion löst. Denke eher nicht das der Austausch der Funktion auch deine Access Violation behebt .
Fridolin Walther
  Mit Zitat antworten Zitat
nat

Registriert seit: 10. Nov 2005
216 Beiträge
 
RAD-Studio 2009 Pro
 
#17

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 14:07
die nicht-rekursive variante klingt logisch. hätte ich auch selber drauf kommen können
aber is das denn nun wirklich schneller? konnte man da nich noch was rausholen wenn man
statt nem dyn. array ne verkettete liste o.ä. nehmen würde?
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#18

Re: Dateien, Unterverzeichnisse zählen?

  Alt 13. Nov 2008, 14:28
Zitat von nat:
die nicht-rekursive variante klingt logisch. hätte ich auch selber drauf kommen können
aber is das denn nun wirklich schneller? konnte man da nich noch was rausholen wenn man
statt nem dyn. array ne verkettete liste o.ä. nehmen würde?
Klar, da kann man noch ne Menge rausholen. Die Liste ist da z.B. ein Ansatz. Dann könnte man den Pfadnamen zwischenspeichern, damit nicht dauernd GetPath aufgerufen wird, was ja jedes Mal fast das komplette Array durchgeht und den Pfad zusammen setzt. Gibt viele Möglichkeiten um da noch deutlich mehr Leistung heraus zu kitzeln. Aber es ging ja nur darum zu zeigen wie man es lösen könnte und nicht um die performanteste Implementation. Das Array ist halt meiner Ansicht nach am einfachsten zu verstehen.
Fridolin Walther
  Mit Zitat antworten Zitat
GerhardS

Registriert seit: 16. Okt 2009
Ort: Berlin
8 Beiträge
 
#19

Re: Dateien, Unterverzeichnisse zählen?

  Alt 16. Okt 2009, 21:03
Vielleicht sehe ich den Wald vor lauter Bäumen nicht: ich brauche eine Funktion, die mir einen Byte-Wert zurückliefert, wieviel Unterverzeichnisse eine Verzeichnis hat.
Hintergrund:
Ich möchte eine Anwendung schreiben, die das Bearbeiten von HTML-Dateien erleichtert. In diesen Dateien werden Pfade in der Regel so ausgedrückt:
MeinBild
Als Ausgangsverzeichnis liegt D:\MeineWebsites\RumsdaBumsda vor, es ist eine 1:1-Kopie der Dateien auf dem Webserver.
Nun möchte ich die maximale Verzeichnistiefe von D:\MeineWebsites\RumsdaBumsda herausfinden, denn damit kann ich mittels SearchTreeForFiles alle Verzeichnisebene durchforsten, ob
"images/myimage.jpg" auf "../images/myimage.jpg" oder "../../images/myimage.jpg" liegt. Wie man sieht, liegt der Unterschied in der Anzahl der von myimage.jpg zur Root liegenden Ebenen.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#20

Re: Dateien, Unterverzeichnisse zählen?

  Alt 16. Okt 2009, 23:22
Zitat von Mattze:
Hallo,

meine Quelle sieht so aus:
Delphi-Quellcode:
type FG = array[0..2] of int64; //Global definiert
     {0 - Größe, 1 - Anzahl Dateien, 2 - Anzahl unterverzeichnisse}
Was ist denn das für ein Konstrukt? Wie wäre es mit einem Record:
Delphi-Quellcode:
type
  TFoo = record
    Size: Int64;
    NumFiles: Integer;
    NumFolders: Integer;
  end;
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz