![]() |
Dateien, Unterverzeichnisse zählen?
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 |
Re: Dateien, Unterverzeichnisse zählen?
Zeig doch mal die rekursive Funktion, damit würde ich das nämlich auch machen.
|
Re: Dateien, Unterverzeichnisse zählen?
'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) |
Re: Dateien, Unterverzeichnisse zählen?
Zitat:
Zitat:
Zitat:
|
Re: Dateien, Unterverzeichnisse zählen?
Zitat:
Zitat:
Zitat:
|
Re: Dateien, Unterverzeichnisse zählen?
Hallo,
meine Quelle sieht so aus:
Delphi-Quellcode:
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!)
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; 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 |
Re: Dateien, Unterverzeichnisse zählen?
Zitat:
Delphi-Quellcode:
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.
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; Zitat:
Zitat:
|
Re: Dateien, Unterverzeichnisse zählen?
Zitat:
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. |
Re: Dateien, Unterverzeichnisse zählen?
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.
|
Re: Dateien, Unterverzeichnisse zählen?
Zitat:
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? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 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