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 17. Okt 2009
Antwort Antwort
Seite 1 von 2  1 2      
Mattze

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

Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 17:49
Hallo,

ich trau mich ja schon fast nicht...

Wie zähle ich günstig ALLE Dateien und Unterverzeichnisse eines Verzeichnisses?
(ALLE meint wirklich alle, also auch die Dateien, die in den Unterverzeichnissen liegen bzw. auch die Unterverzeichnisse von Unterverzeichnissen...)

Ich habe das bisher mit einer rekursiven Funktion gemacht und das geht auch sehr gut. Nur in dem neuen Programm stürzt er mit einer Zugriffsschutzverletzung ganz woanders ab. (In einer völlig fremden Unit, die damit vordergründig gar nichts zu tun hat!)

Vielleicht gibt es da noch eine direktere Möglichkeit?

Gruß
Mattze
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.619 Beiträge
 
Delphi 12 Athens
 
#2

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 17:55
Zeig doch mal die rekursive Funktion, damit würde ich das nämlich auch machen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 17:59
'ne andere Möglichkeit, als die Verzeichnisse rekursiv durchzugehn gibt es doch eigentlich nicht?

Aber ich kann mir nicht vorstellen, wieso soeine Funktion das Programm zum Abstürzen bringen sollte.
Vielleicht solltes du anstatt nach 'ner anderen Möglichkeit zu suchen lieber mal suchen warum der Fehler an der anderen stelle auftritt und diesen Fehler dann beheben.

Das Schnellste und Resourcenschonenste sollte wohl eine Funktion direkt auf Basis der WinAPI sein.
(Die Delphi-Funktionen ala FindFirst machen intern ja noch mehr, da sie ja darauf ausgelegt sind mit einer Maske zu suchen und zu filtern)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Fridolin Walther

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 18:31
Zitat von himitsu:
'ne andere Möglichkeit, als die Verzeichnisse rekursiv durchzugehn gibt es doch eigentlich nicht?
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.

Zitat von himitsu:
Aber ich kann mir nicht vorstellen, wieso soeine Funktion das Programm zum Abstürzen bringen sollte.
Der Stack ist nicht unendlich groß. Je nachdem wir hoch die Rekursionstiefe ist, kanns dann schon mal krachen.

Zitat von himitsu:
(Die Delphi-Funktionen ala FindFirst machen intern ja noch mehr, da sie ja darauf ausgelegt sind mit einer Maske zu suchen und zu filtern)
Der Filter wird eigentlich eins zu eins an die Windows API übergeben. Der einzige Overhead der entsteht besteht darin, das die Informationen aus der Windows Datenstruktur in die Delphi Datenstruktur kopiert werden.
Fridolin Walther
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 18:45
Zitat von 0xF30FC7:
Der Filter wird eigentlich eins zu eins an die Windows API übergeben. Der einzige Overhead der entsteht besteht darin, das die Informationen aus der Windows Datenstruktur in die Delphi Datenstruktur kopiert werden.
also bis D2006 war das noch nicht der Fall und ich kann mir nicht vorstellen, daß die es jetzt noch geändert haben.

Zitat:
Der Stack ist nicht unendlich groß. Je nachdem wir hoch die Rekursionstiefe ist, kanns dann schon mal krachen.
die Verzeichnistiefe ist auch nicht unendlich Groß, also wird es wohl nicht so leicht zum Crash kommen

Zitat:
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.
nur daß es eigentlich nahezu überall rekursiv gelöst wird (nja, so ist es halt auch noch irgendwie einfacher)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Mattze

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 18:51
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}

var FGAbbruch: Boolean = false; //Global definiert

function GetFolderSize(const FolderName: string): FG;
var FN: string;
      ex: fg;
      sr: Tsearchrec;
begin
   result[0]:=0; result[1]:=0; result[2]:=0;
   if FgAbbruch then exit;
   FN:=foldername;
   er:=findfirst(FN+'\*.*',faanyfile,sr);
   while er=0 do begin
      if fgabbruch then begin
        result[0]:=0; result[1]:=0; result[2]:=0;
        break;
      end;
      application.processmessages;
      if (sr.attr and fadirectory = fadirectory) then begin
         if (sr.name<>'..') and (sr.name<>'.') then begin
            inc(result[2]);
            ex:=getfoldersize(fn+'\'+sr.name);
            result[0]:=result[0]+ex[0];
            result[1]:=result[1]+ex[1];
            result[2]:=result[2]+ex[2];
         end
      end else begin
         inc(result[1]);
         result[0]:=result[0]+sr.size;
      end;
      er:=findnext(sr)
   end;
   sysutils.findclose(sr);
end;
Bei der Fremdunit, bei der ein Fehler auftritt, handelt es sich um EasyListview. Da ist es nicht so einfach möglich, alles zu ändern. (Zumal der Fehler an einer sehr wichtigen Stelle auftritt!)

Ich habe es auch mal versucht, das nichtrekursiv zu machen, weil ich eben auch mal gelesen habe, dass man alles rekursive auch nicht rekursiv machen kann. Ich bin da nicht weit gekommen, hab's einfach nicht hingekriegt.
Wie macht man das?

Gruß
Mattze
  Mit Zitat antworten Zitat
Fridolin Walther

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 19:44
Zitat von himitsu:
Zitat von 0xF30FC7:
Der Filter wird eigentlich eins zu eins an die Windows API übergeben. Der einzige Overhead der entsteht besteht darin, das die Informationen aus der Windows Datenstruktur in die Delphi Datenstruktur kopiert werden.
also bis D2006 war das noch nicht der Fall und ich kann mir nicht vorstellen, daß die es jetzt noch geändert haben.
Delphi 2007:
Delphi-Quellcode:
function FindMatchingFile(var F: TSearchRec): Integer;
var
  LocalFileTime: TFileTime;
begin
  with F do
  begin
    while FindData.dwFileAttributes and ExcludeAttr <> 0 do
      if not FindNextFile(FindHandle, FindData) then
      begin
        Result := GetLastError;
        Exit;
      end;
    FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
    FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi,
      LongRec(Time).Lo);
    Size := FindData.nFileSizeLow or Int64(FindData.nFileSizeHigh) shl 32;
    Attr := FindData.dwFileAttributes;
    Name := FindData.cFileName;
  end;
  Result := 0;
end;

function FindFirst(const Path: string; Attr: Integer;
  var F: TSearchRec): Integer;
const
  faSpecial = faHidden or faSysFile or faDirectory;
begin
  F.ExcludeAttr := not Attr and faSpecial;
  F.FindHandle := FindFirstFile(PChar(Path), F.FindData);
  if F.FindHandle <> INVALID_HANDLE_VALUE then
  begin
    Result := FindMatchingFile(F);
    if Result <> 0 then FindClose(F);
  end else
    Result := GetLastError;
end;
FindMatchingFile führt zwar Filterung durch auf Grund der angegebenen Attribute, aber der Vergleich bzw. die Bitweisen Operationen kaum ins Gewicht. Die von Dir angesprochene "Maske" wird 1 zu 1 an Windows übergeben.

Zitat von himitsu:
die Verzeichnistiefe ist auch nicht unendlich Groß, also wird es wohl nicht so leicht zum Crash kommen
Das kommt darauf an, wie die Systemsettings aussehen. Wie groß ist der Stack z.B. letztlich bzw. was ist angefordert. Dann kommt es darauf an ob und was für lokale Variablen auf dem Stack liegen. So ein Stacklimit überschreitet man bei Rekursion schneller als man denkt. Die maximale Pfadlänge beträgt bei NTFS 32767 Zeichen. Bedeutet Rekursionstiefen von 10000+ sind problemlos machbar (Pfad: \\.\C:\A\A\A\A\A\...). Wenn Du dann bei jeder Funktion n 50 kb Array auf dem Stack liegen hast, krachts.

Zitat von himitsu:
nur daß es eigentlich nahezu überall rekursiv gelöst wird (nja, so ist es halt auch noch irgendwie einfacher)
Nur weil andere es auch falsch machen, wirds dadurch nicht besser ...
Fridolin Walther
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 20:14
Zitat:
Pfad: \\.\C:\A\A\A\A\A\...
Aber mal ganz im Ernst, wie oft kommt sowas vor?

Die 32767 Zeichen kommen nur in Verbindung mit UNC-Pfadnamen vor ... ansonsten ist bei 259 Zeichen Schluß. (MAX_PATH - die letzte #0)
Und ich glaub kaum, daß er in seinem Programm UNC verwendet.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 20:29
Ganz unberichtigt ist die Aussage das der Stack nicht unendlich groß ist nicht. Denn man kann unter anderem bei NTFS in einen Ordner eine Partition einhängen/mounten. Hat man also das Laufwerk C und drauf den Ordner A kann man in Ordner A durchaus auch wieder die Partition von Laufwerk C einhängen. Daraus resultiert eine unendliche Pfadtiefe. So etwas sollte man eventuell auch berücksichtigen. Eventuell durch festlegen einer maximalen Pfadtiefe um keine Endlosrekursion zu haben.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Fridolin Walther

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

Re: Dateien, Unterverzeichnisse zählen?

  Alt 12. Nov 2008, 20:50
Zitat von himitsu:
Zitat:
Pfad: \\.\C:\A\A\A\A\A\...
Aber mal ganz im Ernst, wie oft kommt sowas vor?

Die 32767 Zeichen kommen nur in Verbindung mit UNC-Pfadnamen vor ... ansonsten ist bei 259 Zeichen Schluß. (MAX_PATH - die letzte #0)
Und ich glaub kaum, daß er in seinem Programm UNC verwendet.
Da wäre eine Rekursionstiefe von 125+ möglich. Das reicht mitunter für nen Crash. Kommt auf die lokalen Variablen an und wie groß der Stack werden darf.

Aber ansonsten ordne ich solche Aussagen wie "Das kommt so selten vor" immer in die "Famous last words" Kategorie ein . Ist nicht bös gemeint, aber ich erinner mich da immer an eine lustige Unterhaltung nach nem Code Audit. Zitat Entwickler: "Da würde doch niemals jemand auf die Idee kommen dort mehr als 255 Zeichen für einen Usernamen zu verwenden." Zwei Monate später gabs dann nen Exploit auf milw0rm.

Aber um wieder OnTopic zu werden:
An der Routine selbst ist nichts auszusetzen, ausser halt das der Stack ausgehen kann (was aber eher unwahrscheinlich ist, ich gebs ja zu). Hast Du aus der Funktion evtl. was rausgekürzt? Evtl. Zugriffe auf das Treeview bei dem es dann crashed? In welchem Kontext wird die Funktion ausgeführt? Aus dem Hauptthread heraus? Rennts in nem extra Thread? Wie lautet die exakte Fehlermeldung?
Fridolin Walther
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 14:00 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