Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Ordnergröße ermitteln (https://www.delphipraxis.net/214279-ordnergroesse-ermitteln.html)

DieDolly 16. Dez 2023 17:21


Ordnergröße ermitteln
 
Ich finde dazu leider nur altes Zeug von vor über 10 Jahren.
Wie ermittelt man heute Ordnergrößen? Ich nutze dazu aktuell JclFileUtils.GetDirectorySize(), möchte abewr komplett vopnm Jcl weg.

jaenicke 16. Dez 2023 21:21

AW: Ordnergröße ermitteln
 
Vielleicht hilft dir das weiter:
https://entwickler-ecke.de/topic_MDirStat_114798.html

Ansonsten gibt es noch Funktionen in der Unit System.IOUtils zur Auflistung von Dateien usw., die hilfreich sein könnten. Allerdings musst du da aufpassen mit Junctions usw., was in dem obigen Tool bereits berücksichtigt wird.

himitsu 16. Dez 2023 22:20

AW: Ordnergröße ermitteln
 
Leider fehlt immernoch etwas Wichtiges,
https://quality.embarcadero.com/browse/RSP-41662

aber
Delphi-Quellcode:
  var Size: Int64 := 0;
  TDirectory.GetFiles('C:\Users', '*.jpg', TSearchOption.soAllDirectories,
    function(const Path: string; const SearchRec: TSearchRec): Boolean
    begin
      Inc(Size, SearchRec.Size);
    end);
  ShowMessage(Size.ToString);
Wobei es in 85 Jahren vielleicht mal irgendwie so aussehn könnte
Delphi-Quellcode:
  var Size: Int64 := 0;
  for var FileEntry in TDirectory.GetFileIrgendwas('C:\Users', '*.jpg', soAllDirectories) do
    Inc(Size, FileEntry.Size);
  ShowMessage(Size.ToString);

KodeZwerg 16. Dez 2023 23:16

AW: Ordnergröße ermitteln
 
Nur so aus dem Bauch heraus, noch nicht getested da nur hier getippt...
Delphi-Quellcode:
uses System.IOUtils;

function GetDirectorySize(const Dir: string): Int64;
var
 Files: TArray<string>;
 SubDirs: TArray<string>;
 FileSize: Int64;
 i: Integer;
begin
 Result := 0;
 Files := TDirectory.GetFiles(Dir);
 for i := 0 to High(Files) do
   Result := Result + TFile.GetSize(Files[i]);
 SubDirs := TDirectory.GetDirectories(Dir);
 for i := 0 to High(SubDirs) do
   Result := Result + GetDirectorySize(SubDirs[i]);
end;

mytbo 16. Dez 2023 23:27

AW: Ordnergröße ermitteln
 
Zitat:

Zitat von himitsu (Beitrag 1530897)
Wobei es in 85 Jahren vielleicht mal irgendwie so aussehn könnte

Ist schon heute möglich:
Delphi-Quellcode:
uses
  mormot.core.text,
  mormot.core.search;

begin
  var size: Int64 := 0;
  for var run: TFindFiles in FindFiles('c:\Users\', '*.png;*.jpg;*.jpeg', '', [ffoSubFolder]) do
    Inc(size, run.Size);
  ShowMessage(Format('Size: %s', [KB(size)])); // Size: 210.5 MB
Bis bald...
Thomas

himitsu 17. Dez 2023 03:58

AW: Ordnergröße ermitteln
 
@KodeZwerg:

GetFiles kann auch direkt Rekursiv,
bzw. man kann sich Dateien und Verzeichnisse auch gleichzeitig geben lassen.

Ja, es gibt TFile.GetSize
aber das fragt somit mehrmals das selbe Verzeichnis ab, einmal für den Dateinamen und nochmal für die Größe.

Blöd dabei ist dann, dass FindFiles/GetFiles bereits die Dateigröße mit abgefragt hatte,
aber die neuen Delphi-Funktionen zu dämlich sind, das uns rauszugeben (außer eben innerhalb des "Filters")

Wenn du schon selbst das Rekursive machen willst, dann nimm besser die "alten" FindFiles (FindFirstFile),
da bekommst'e dann auch mit einer Abfrage Dateien+Verzeichnisse und dann in der Schleife nur noch Inc bei Datei und das Rekursive wenn Verzeichnis.

DieDolly 17. Dez 2023 13:55

AW: Ordnergröße ermitteln
 
Danke für die Antworeten. Ich habe mir den Code aus JclUtils genommen und angepasst.
Delphi-Quellcode:
function GetDirectorySize(const Path: string): Int64;
 function RecurseFolder(const Path: string): Int64;
 var
  F: TSearchRec;
  R: Integer;
  TempSize: TWin32FileAttributeData;
 begin
  Result := 0;
  R := System.SysUtils.FindFirst(Path + '*.*', faAnyFile, F);
  if R = 0 then
   try
    while R = 0 do
     begin
      if (F.Name <> '.') and (F.Name <> '..') then
       begin
        if (F.Attr and faDirectory) = faDirectory then
         Inc(Result, RecurseFolder(Path + F.Name + '\'))
        else
         begin
          TempSize.nFileSizeLow := F.FindData.nFileSizeLow;
          TempSize.nFileSizeHigh := F.FindData.nFileSizeHigh;
          Inc(Result, TempSize.nFileSizeHigh shl 32 + TempSize.nFileSizeLow);
         end;
       end;
      R := System.SysUtils.FindNext(F);
     end;
    if R <> ERROR_NO_MORE_FILES then
     Abort;
   finally
    System.SysUtils.FindClose(F);
   end;
 end;

begin
 if not DirectoryExists(ExcludeTrailingBackslash(Path)) then
  Result := -1
 else
  try
   Result := RecurseFolder(IncludeTrailingBackslash(Path))
  except
   Result := -1;
  end;
end;

himitsu 17. Dez 2023 14:31

AW: Ordnergröße ermitteln
 
https://docwiki.embarcadero.com/Libr...SearchRec.Size

Und TempSize.nFileSizeHigh vor dem Shift nicht auf 64 Bit zu casten, dürfte auch viel Spaß bereiten.

DieDolly 17. Dez 2023 16:47

AW: Ordnergröße ermitteln
 
Zitat:

Und TempSize.nFileSizeHigh vor dem Shift nicht auf 64 Bit zu casten, dürfte auch viel Spaß bereiten.
Wie wäre es richtig? So in etwa ist es auch in der JclFileUtils.pas.

So?
Delphi-Quellcode:
Inc(Result, (Int64(TempSize.nFileSizeHigh) shl 32) + TempSize.nFileSizeLow);

himitsu 17. Dez 2023 16:57

AW: Ordnergröße ermitteln
 
Nja, das ist ein 32-Bit UInt und wenn man da alles um 32 Bit nach links verschiebt, dann rutscht alles raus und ist weg.
Der Compiler kommt auch nicht immer auf die Idee sowas von sich aus einfach so zu vergrößern (normal maximal bis zur Größe eines Registers)

So
Delphi-Quellcode:
:= Int64(TempSize.nFileSizeHigh) shl 32 or TempSize.nFileSizeLow;
wäre es demnach schon sicherer,

aber wie schon genannt ... Warum nicht einfach F.Size, anstatt F.FindData.nFileSize* ? :angle:



PS: Da wir hier Signed rechnen, ist es binär sicherer, als arithmetisch.

OK, man könnte auch
Delphi-Quellcode:
:= Int64(UInt64(TempSize.nFileSizeHigh) shl 32) + TempSize.nFileSizeLow;
, aber warum.
z.B. gäbe es Probleme und die Größe wäre z.B. -1, dann würde es nach Umrechnung mit einer signed Addition einen anderen Wert ergeben.

Alternativ einfach nur casten und garnicht rechnen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 Uhr.
Seite 1 von 2  1 2      

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