Einzelnen Beitrag anzeigen

Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Belegter Speicherplatz von Verzeichnissen ermitteln?

  Alt 24. Mär 2022, 16:41
Delphi-Quellcode:
Unit22;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm22 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Memo1: TMemo;
    CheckBox1: TCheckBox;
    FileOpenDialog1: TFileOpenDialog;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form22: TForm22;

implementation

{$R *.dfm}

uses
  System.IOUtils;

type
  TMyFile = packed record
    Folder: string;
    Filename: string;
    Filesize: Int64;
    Archive: Boolean;
    ReadOnly: Boolean;
    Hidden: Boolean;
    System: Boolean;
  end;

  TMyFiles = array of TMyFile;
  TMyFolders = array of string;

  TMyFileSystem = class (TPersistent)
    strict private
      FContent: TMyFiles;
      FFolderNames: TMyFolders;
      FFolderCount: Int64;
      FFileCount: Int64;
      FSize: Int64;
      FBaseFolder: string;
      FIncludeSub: Boolean;
    protected
      procedure AddFile(const APath: string);
      procedure AddFolder(const APath: string);
    private
      procedure Reset;
      procedure Init(const APath: string; const AIncludeSub: Boolean = False);
      procedure SetBaseFolder(const APath: string);
    public
      constructor Create(const APath: string; const AIncludeSub: Boolean = False); overload;
      constructor Create(); overload;
      destructor Destroy; override;
    public
      property BaseFolder: string read FBaseFolder write SetBaseFolder;
      property IncludeSub: Boolean read FIncludeSub write FIncludeSub;
      property Files: Int64 read FFileCount;
      property Folders: Int64 read FFolderCount;
      property Size: Int64 read FSize;
      property FileItems: TMyFiles read FContent;
      property FolderItems: TMyFolders read FFolderNames;
  end;

constructor TMyFileSystem.Create(const APath: string; const AIncludeSub: Boolean = False);
begin
  inherited Create;
  Self.Reset;
  Self.Init(APath, AIncludeSub);
end;

constructor TMyFileSystem.Create();
begin
  inherited Create;
  Self.Reset;
end;

destructor TMyFileSystem.Destroy;
begin
  Self.Reset;
  inherited Destroy;
end;

procedure TMyFileSystem.Reset;
begin
  SetLength(FContent, 0);
  SetLength(FFolderNames, 0);
  FFolderCount := 0;
  FFileCount := 0;
  FSize := 0;
  FBaseFolder := '';
  FIncludeSub := False;
end;

procedure TMyFileSystem.SetBaseFolder(const APath: string);
begin
  Self.Reset;
  Self.Init(APath, FIncludeSub);
end;

procedure TMyFileSystem.Init(const APath: string; const AIncludeSub: Boolean = False);
var
  LString: string;
begin
  FIncludeSub := AIncludeSub;
  if TDirectory.Exists(APath) then
    begin
      FBaseFolder := APath;
      case AIncludeSub of
        True: begin
                 for LString in TDirectory.GetFiles(FBaseFolder, '*', TSearchOption.soAllDirectories) do
                   Self.AddFile(LString);
                 for LString in TDirectory.GetDirectories(FBaseFolder, '*', TSearchOption.soAllDirectories) do
                   Self.AddFolder(LString);
               end;
        False: begin
                 for LString in TDirectory.GetFiles(FBaseFolder, '*', TSearchOption.soTopDirectoryOnly) do
                   Self.AddFile(LString);
                 for LString in TDirectory.GetDirectories(FBaseFolder, '*', TSearchOption.soTopDirectoryOnly) do
                   Self.AddFolder(LString);
               end;
      end;
    end;
end;

procedure TMyFileSystem.AddFile(const APath: string);
  function MyGetFileSize(const APath: String): Int64;
    var
      Win32FileAttributeData: TWin32FileAttributeData;
    begin
      Result := -1;
      if (not GetFileAttributesEx(PChar(APath), GetFileExInfoStandard, @Win32FileAttributeData)) then
        Exit;
      Result := Int64(Win32FileAttributeData.nFileSizeLow) or Int64(Win32FileAttributeData.nFileSizeHigh shl 32);
    end;
var
  i: Integer;
  FileAttributes: TFileAttributes;
begin
  i := Length(FContent);
  SetLength(FContent, i + 1);
  FContent[i].Folder := ExtractFilePath(APath);
  FContent[i].Filename := ExtractFileName(APath);
  FileAttributes := TFile.GetAttributes(APath, False);
  FContent[i].ReadOnly := (TFileAttribute.faReadOnly in FileAttributes);
  FContent[i].Hidden := (TFileAttribute.faHidden in FileAttributes);
  FContent[i].System := (TFileAttribute.faSystem in FileAttributes);
  FContent[i].Archive := (TFileAttribute.faArchive in FileAttributes);
  FContent[i].Filesize := MyGetFileSize(APath);
  Inc(FFileCount, 1);
  FSize := FSize + FContent[i].Filesize;
end;

procedure TMyFileSystem.AddFolder(const APath: string);
var
  i: Integer;
begin
  i := Length(FFolderNames);
  SetLength(FContent, i + 1);
  FFolderNames[i] := ExtractFileName(APath);
  Inc(FFolderCount);
end;

procedure TForm22.Button1Click(Sender: TObject);
var
  FileSystem: TMyFileSystem;
begin
  if FileOpenDialog1.Execute then
    begin
      FileSystem := TMyFileSystem.Create(FileOpenDialog1.FileName, CheckBox1.Checked);
      try
        for i := 0 to FileSystem.Files - 1 do
          Memo1.Lines.Add({FileSystem.FileItems[i].Folder +} FileSystem.FileItems[i].Filename);
        Label1.Caption := FileSystem.BaseFolder;
        Label2.Caption := UIntToStr(FileSystem.Size);
      finally
        FileSystem.Free;
      end;
    end;
end;


end.
hatte ich mal auf die schnelle für einen discord user getippst, sind bestimmt noch optimierungen vorhanden aber grundsätzlich macht es was es soll.
vielleicht hilft es?
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat