Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Dateigröße ermitteln, wie geht Ihr vor? (https://www.delphipraxis.net/195004-dateigroesse-ermitteln-wie-geht-ihr-vor.html)

Fukiszo 25. Jan 2018 21:29

Dateigröße ermitteln, wie geht Ihr vor?
 
Hi, hier ein beispiel wie ich es mit Delphi mache

Delphi-Quellcode:
// return -1 if file not found else size in byte
function lwFileSize(sFileToExamine: string) : Longint;
var
  fFile : file of Byte;
begin
  Result := -1;
  if FileExists(sFileToExamine) then
  try
    FileMode := 0;
    AssignFile(fFile, sFileToExamine);
    Reset(fFile);
    Result := FileSize(fFile);
  finally
    Close(fFile);
  end;
end;
ist diese art und weise veraltet und überholt?

Grüße

ps: ich wusst nicht wohin deshalb ist es hier gelandet.

LTE5 25. Jan 2018 21:41

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
So ist es um einiges schneller

Delphi-Quellcode:
function lwFileSize(const aFileName: string): Int64;
var
 FileInfo: TWin32FileAttributeData;
begin
 Result := -1;

 FillChar(FileInfo, SizeOf(FileInfo), 0);
 if GetFileAttributesEx(PChar(aFileName), GetFileExInfoStandard, @FileInfo) then
  begin
   Int64Rec(Result).Hi := FileInfo.nFileSizeHigh;
   Int64Rec(Result).Lo := FileInfo.nFileSizeLow;
  end;
end;

Fukiszo 25. Jan 2018 23:06

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
danke für deinen vorschlag, ich versuche das was jetzt kommt in eine delphi ide vcl variante umzubauen,
das liest ein verzeichniss ein und gibt dateien in eine ListView mit icon und paar info's wieder.

Delphi-Quellcode:
procedure GetFiles(const hLV: HWND; Path, Mask: String);
var
  finddata : TWin32FindData;
  hFile   : cardinal;
  Loop    : dword;
  lvi     : TLVItem;
  buf     : array[0..25]of char;
  tile    : TLVTileInfo;
  fi      : TSHFileInfo;
  LVIMark : TLVInsertMark;
  tmp     : String;
  i       : integer;
begin
 hFile := FindFirstFile(PChar(IncludeTrailingPathDelimiter(Path) + Mask), finddata);
  if(hFile <> INVALID_HANDLE_VALUE) then begin
   LockWindowUpdate(hDlg);
   LastFolder := IncludeTrailingPathDelimiter(Path);
   Loop := 0;
    repeat
     if(finddata.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0) then begin

      ZeroMemory(@fi, sizeof(TSHFileInfo));
      ListView_SetImageList(hLV,
       SHGetFileInfo(PChar(IncludeTrailingPathDelimiter(Path) + finddata.cFilename), 0,
       fi, sizeof(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_TYPENAME or SHGFI_SMALLICON), LVSIL_SMALL);

      ZeroMemory(@fi, sizeof(TSHFileInfo));
      ListView_SetImageList(hLV,
       SHGetFileInfo(PChar(IncludeTrailingPathDelimiter(Path) + finddata.cFilename), 0,
       fi, sizeof(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_TYPENAME or SHGFI_ICON), LVSIL_NORMAL);

      lvi.mask    := LVIF_TEXT or LVIF_IMAGE;
      lvi.iItem   := Loop;
      lvi.iSubItem := 0;
      lvi.pszText := finddata.cFileName;
     i := 0;
      lvi.iImage  := fi.iIcon;
      ListView_InsertItem(hLV, lvi);

      tmp := IntToStr(finddata.nFileSizeLow)+' byte';
      if (finddata.nFileSizeLow / 1024) > 1 then tmp := FloatToStr((finddata.nFileSizeLow / 1024),-1,2)+' kb';
      if (finddata.nFileSizeLow / 1024 / 1024) > 1 then tmp := FloatToStr((finddata.nFileSizeLow / 1024 / 1024),-1,2)+' mb';
      if (finddata.nFileSizeLow / 1024 / 1024 / 1024) > 1 then tmp := FloatToStr((finddata.nFileSizeLow / 1024 / 1024 / 1024),-1,2)+' gb';
      lvi.mask    := LVIF_TEXT;
      lvi.iSubItem := 1;
      lvi.pszText := pChar(tmp);
      ListView_SetItem(hLV, lvi);

      lvi.mask    := LVIF_TEXT;
      lvi.iSubItem := 2;
      lvi.pszText := fi.szTypeName;
      ListView_SetItem(hLV, lvi);

//      ZeroMemory(@buf, sizeof(buf));
//      wvsprintf (buf, '%u byte', pchar(@finddata.nFileSizeLow));
      lvi.mask    := LVIF_TEXT;
      lvi.iSubItem := 3;
      lvi.pszText := pChar(IntToStr(finddata.nFileSizeLow)); //buf;
      ListView_SetItem(hLV, lvi);

     if GetOSVersion = osXP then begin
      tile.cbSize   := sizeof(TLVTileInfo);
      tile.iItem    := Loop;
//     tile.cColumns := length(colArray);
      tile.puColumns := @colArray[0];
      ListView_SetTileInfo(hLV, tile);
     end;
    LVIMark.cbSize    := sizeof(TLVInsertMark);
    LVIMark.dwFlags   := LVIM_AFTER;
    LVIMark.iItem     := Loop;
    LVIMark.dwReserved := 0;
    ListView_SetInsertMark(hLV, LVIMark);
    if LowerCase(ExtractFileName(SelectedFile)) = LowerCase(finddata.cFileName) then
    begin
{     if LowerCase(ExtractFileName(SelectedFile)) = LowerCase(finddata.cFileName) then
      ListView_SetItemState(hLV, Loop, 0, LVIS_SELECTED);}
      lvi.stateMask := LVIS_SELECTED;
      lvi.state := LVIS_SELECTED;
      SendMessage(hLV, LVM_SETITEMSTATE, Loop, Longint(@lvi))
    end;
    Inc(Loop);
   end;
  until (not FindNextFile(hFile, finddata));
   FindClose(hFile);
  LockWindowUpdate(0);
 end;
end;
vielleicht kann man das auch "tunen" ?

Grüße

LTE5 25. Jan 2018 23:32

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
Hier würde ich ein VirtualStringTree verwenden.

Der schöne Günther 26. Jan 2018 09:41

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
Ich mache es haargenau gleich wie LTE5

Delphi-Quellcode:
class function TFileHelper.GetSize(const fileName: String): Int64;
var
   info: TWin32FileAttributeData;
begin
   if not TFile.Exists(fileName) then
      raise EFileNotFoundException.CreateRes(@SFileNotFound);

   // Quelle: http://stackoverflow.com/a/1642355/2298252
   if not GetFileAttributesEx(
      PChar(fileName),
      WinApi.Windows.GetFileExInfoStandard,
      Addr(info)
   ) then RaiseLastOSError();

   Result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;

himitsu 26. Jan 2018 09:58

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
Warum doppelt abfragen?
Delphi-Quellcode:
class function TFileHelper.GetSize(const fileName: String): Int64;
var
   info: TWin32FileAttributeData;
begin
   if not GetFileAttributesEx(PChar(fileName), GetFileExInfoStandard, @info) then
     RaiseLastOSError;
   Result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;
Wenn es aber unbedingt EFileNotFoundException sein soll, dann halt
Delphi-Quellcode:
class function TFileHelper.GetSize(const fileName: String): Int64;
var
   info: TWin32FileAttributeData;
begin
   if not GetFileAttributesEx(PChar(fileName), GetFileExInfoStandard, @info) then
     if GetLastError in [ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND] then
       raise EFileNotFoundException.CreateRes(@SFileNotFound)
     else
       RaiseLastOSError;
   Result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;

freimatz 26. Jan 2018 10:29

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
@Fukiszo: Empfehle http://www.delphipraxis.net/162373-t...t-ihr-vor.html

Fukiszo 26. Jan 2018 11:47

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
Danke für all eure Vorschläge und Mühe

Code:
// von LTE5
function lwFileSize(const aFileName: string): Int64;
var
 FileInfo: TWin32FileAttributeData;
begin
 Result := -1;
 FillChar(FileInfo, SizeOf(FileInfo), 0); // das hier evtl weglassen, muss ich selbst erst nachvollziehen können warum
 if GetFileAttributesEx(PChar(aFileName), GetFileExInfoStandard, @FileInfo) then
  begin
   Int64Rec(Result).Hi := FileInfo.nFileSizeHigh;
   Int64Rec(Result).Lo := FileInfo.nFileSizeLow;
  end;
end;
das hier klappt wie gewünscht (bei "file not found" = -1) für mich und die routine arbeitet wirklich schneller
wobei ich total geneigt bin auch das hier dafür zu verwenden:

Code:
// von mehreren DP teilnehmern, hier kann man rückgabewert verintensivieren
// (für externe fehlerbestimmung ist's so besser, sonst evtl dutzende fehlermeldungen falls in einer loop aufgerufen)
// -1 file not found
// -2 general error
// >= 0 filesize in byte
function lwFileSize(const fileName: String): Int64;
var
   info: TWin32FileAttributeData;
begin
   if not GetFileAttributesEx(PChar(fileName), GetFileExInfoStandard, @info) then // tatsächlich pChar ja? (Unicode dingens)
     if GetLastError in [ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND] then
       result := -1 //raise EFileNotFoundException.CreateRes(@SFileNotFound)
     else
       result := -2 // RaiseLastOSError;
   Result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;
Grüße & Danke

himitsu 26. Jan 2018 13:10

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
Wenn es die API GetFileAttributesEx ausschließlich nur als Unicode gäbe, dann PWideChar und ein Unicode-String (den "String" nach Unicode casten).
Schwer zu verstehen ist das ja nun nicht wirklich:
GetFileAttributesEx + PChar + String ... natürlich nur, wenn diese Funktion auch compilerabhänig deklariert wurde.
GetFileAttributesExA + PAnsiChar + AnsiString
GetFileAttributesExW + PWideChar + WideString/UnicodeString

Als Funktion existiert "GetFileAttributesEx" ja eigentlich garnicht. Nur als "unabhängige" Definition.
Delphi-Quellcode:
function GetFileAttributesEx(lpFileName: PChar; fInfoLevelId: TGetFileExInfoLevels; lpFileInformation: Pointer): BOOL; stdcall;
function GetFileAttributesExA(lpFileName: PAnsiChar; fInfoLevelId: TGetFileExInfoLevels; lpFileInformation: Pointer): BOOL; stdcall;
function GetFileAttributesExW(lpFileName: PWideChar; fInfoLevelId: TGetFileExInfoLevels; lpFileInformation: Pointer): BOOL; stdcall;

function GetFileAttributesEx; external kernel32 name {$IFDEF UNICODE}'GetFileAttributesExW'{$ELSE}'GetFileAttributesExA'{$ENDIF};
function GetFileAttributesExA; external kernel32 name 'GetFileAttributesExA';
function GetFileAttributesExW; external kernel32 name 'GetFileAttributesExW';

Sowas ist auch immer ganz nett.
Delphi-Quellcode:
GetFileSize(const aFileName: string; NoException: Boolean=False): Int64;
Ausnahmen behandle ich gern auch als Exceptions.
Wenn die Datei nicht existiert, deren Datum ich wissen will, dann ist das eine Ausnahme.

Aber falls ich doch mal prüfen will und es mit erstmal egal ist, ob die Datei existiert, dann kann man so die Exception deaktivieren, ohne ein Try-Except drummachen zu müssen.

LTE5 26. Jan 2018 14:47

AW: Dateigröße ermitteln, wie geht Ihr vor?
 
Zitat:

Wenn es die API GetFileAttributesEx ausschließlich nur als Unicode gäbe, dann PWideChar und ein Unicode-String (den "String" nach Unicode casten).
Schwer zu verstehen ist das ja nun nicht wirklich:
GetFileAttributesEx + PChar + String ... natürlich nur, wenn diese Funktion auch compilerabhänig deklariert wurde.
GetFileAttributesExA + PAnsiChar + AnsiString
GetFileAttributesExW + PWideChar + WideString/UnicodeString

Als Funktion existiert "GetFileAttributesEx" ja eigentlich garnicht. Nur als "unabhängige" Definition.
Was möchtest du damit nun sagen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:58 Uhr.
Seite 1 von 3  1 23      

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