Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Dateigröße ohne Öffnen der Datei berechnen (https://www.delphipraxis.net/100403-dateigroesse-ohne-oeffnen-der-datei-berechnen.html)

Nils_13 27. Sep 2007 20:00


Dateigröße ohne Öffnen der Datei berechnen
 
Hi,

ich möchte von allen Dateien die Dateigröße anzeigen lassen können. Bisher tat es immer diese Funktion:
Delphi-Quellcode:
function GetFileSize(const FileName : String): Int64;
var FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
  try
    try
      Result := FileStream.Size;
    except
      Result := 0;
    end;
  finally
    FileStream.Free;
  end;
end;
Wenn ich allerdings die Größe meiner Auslagerungsdatei haben möchte, kriege ich wegen dem FileStream sofort eine Zugriffsverletzung, da man nicht die Berechtigung hat, diese Datei zu öffnen. Wie könnte man dennoch die größe bestimmen ?

marabu 27. Sep 2007 20:05

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Hallo Nils,

schau mal hier: dateigroesse ermitteln ohne datei zu oeffnen

Grüße vom marabu

SubData 27. Sep 2007 20:05

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Edit: zu langsam...

marabu 27. Sep 2007 20:08

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Der gute Wille zählt auch.

Nils_13 27. Sep 2007 20:14

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Habe ich doch tatsächlich übersehen....
Delphi-Quellcode:
function GetFileSize(szFile : PChar) : Int64;
var fFile : THandle;
    wfd  : TWIN32FINDDATA;
begin
  Result := -1;
  fFile := FindFirstfile(PChar(szFile), wfd);
  if fFile = INVALID_HANDLE_VALUE then
    Exit;
  Result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  Windows.FindClose(fFile);
end;
Rufe ich die wie oben auf, bloß dass ich anstelle von PWideChar einfach PChar nehme ?
Delphi-Quellcode:
TreeData.fGroesse := BytesToStr(GetFileSize(PChar(Msg.LParam)));

OregonGhost 27. Sep 2007 20:43

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Das ist jetzt vielleicht eine blöde Frage, aber was spricht eigentlich gegen MSDN-Library durchsuchenGetFileAttributesEx?

Nils_13 27. Sep 2007 20:56

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Nichts, habe bloß nicht dran gedacht.

Delphi-Quellcode:
function GetFileSize(f : PAnsiChar) : Int64;
var FI : TWin32FileAttributeData;
begin
  Result := 0;
  if GetFileAttributesEx(f, GetFileExInfoStandard, @FI) then
    Result := FI.nFileSizeHigh;
end;
Das ergibt bei mir allerdings - genauso wie bei Luckies Funktion - den vorgesetzten Ergebniswert (in dem Fall 0).
Merkwürdiger Weise habe ich immer den Laufwerksbuchstaben "E" als Eingabe-PAnsiChar, es wundert mich, wie das mit der alten Funktion funktionieren konnte.

Nachtrag: Es liegt am AnsiChar, es MUSS WideChar benutzt werden, sonst gibt es Salat....

OregonGhost 27. Sep 2007 21:04

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Naja, dass in nFileSizeHigh 0 steht, finde ich nicht direkt überraschend, wenn die Datei nicht gerade größer als 4GB ist. Vielleicht mal (sinngemäß)
Delphi-Quellcode:
(nFileSizeHigh shl 32) or nFileSizeLow
probieren? :)

Übrigens ist mir aufgefallen, dass im Online-MSDN die Mindestanforderung Windows 2000 ist, laut Windows Vista SDK jedoch Windows 98/NT4. Wie unangenehm, dass da auch langsam der Support für die alten Windows-Versionen endet. Ich fand es eigentlich immer ganz angenehm, zu wissen, ob mein Programm theoretisch auch unter Windows 98 laufen würde.

Edit @Nachtrag: Müsstest du nicht auch GetFileAttributesExA benutzen können?

Nils_13 27. Sep 2007 21:10

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Ah, das funzt endlich fast überall, danke. Die Pagefile.sys ist mommentan bei 0 Bytes kann man das noch verbessern ? Man kann GetFileAttributesExA benutzen. Dass die Abwärtskompatibilität immer mehr abnimmt, ist wirklich schade.

OregonGhost 27. Sep 2007 21:13

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Zeigen die anderen geposteten Funktionen für diese Datei denn auch 0 an? Wie groß ist die Datei denn? Nicht, dass sie zufällig 4GB groß ist und deshalb nFileSizeLow 0 ist und nFileSizeHigh 1 und da nur was beim Casten/Shiften schiefgelaufen ist *g*

@Roter Kasten bzgl. Abwärtskompatibilität: Sie nimmt ja nicht ab in dem Sinne, sondern sie wird nicht mehr dokumentiert. Bisher fand man im Windows SDK die Angaben teilweise bis vor Windows 98/NT4 runter. Aber die sind ja nicht mehr offiziell.

Nils_13 27. Sep 2007 21:17

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Mein Fehler war, wie schon angedeutet, dass ich nFileSizeHigh, statt nFileSizeLow genommen habe.

Arbeitskompatibilität: Wenn es keine Dokumentationen mehr gibt, werden viele die Abwärtskompatibilität nicht mehr "nutzen", weil es ihnen zu aufwendig wäre oder man weiß nicht, was einem unter Win98 erwartet. Alles in allem kann man denke ich sagen, dass man immer möglichst plattformunabhängig bleiben sollte, also alle APIs meiden sollte. Da das hier ein pures Windowsprogramm wird, kann mir das ausnahmsweise mal egal sein :)

jbg 27. Sep 2007 21:35

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Zitat:

Zitat von Nils_13
Arbeitskompatibilitä

Du könntest GetFileAttributesEx auch so nutzen, wie CodeGear das in Delphi 2007 bei FileAge macht.

Delphi-Quellcode:
function GetFileAttributesExPreload(lpFileName: PChar; fInfoLevelId: TGetFileExInfoLevels;
  lpFileInformation: Pointer): BOOL; stdcall;
  forward;

var
  { Diesen Funktion-Zeiger kann man nun aufrufen }
  GetFileAttributesExFunc: function(lpFileName: PChar; fInfoLevelId: TGetFileExInfoLevels;
    lpFileInformation: Pointer): BOOL; stdcall = GetFileAttributesExPreload;

{ Use FindFirstFile as an alternative on systems that do not support the GetFileAttributesEx }
function GetFileAttributesExEmulated(lpFileName: PChar; fInfoLevelId: TGetFileExInfoLevels;
  lpFileInformation: Pointer): BOOL; stdcall;
var
  Handle: THandle;
  FindData: TWin32FindData;
begin
  Handle := FindFirstFile(lpFileName, FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    if lpFileInformation <> nil then
    begin
      Move(FindData, lpFileInformation^, SizeOf(TWin32FileAttributeData));
      Result := True;
      Exit;
    end;
  end;
  Result := False;
end;

function GetFileAttributesExPreload(lpFileName: PChar; fInfoLevelId: TGetFileExInfoLevels;
  lpFileInformation: Pointer): BOOL; stdcall;
begin
  GetFileAttributesExFunc := GetProcAddress(GetModuleHandle(kernel32), 'GetFileAttributesExA');
  if not Assigned(GetFileAttributesExFunc) then
    GetFileAttributesExFunc := GetFileAttributesExEmulated;
  Result := GetFileAttributesExFunc(lpFileName, fInfoLevelId, lpFileInformation);
end;
Da fällt mir gerade auf, dass ich haar genau den selben Code doch in DelphiSpeedUp benutze und das bevor Delphi 2007 überhaupt das Licht der Welt erblickte. Sogar die Namensgleichheit der Funktionen ...Emulated und ...Preload ist verblüffend. Wo die den Code nur her haben :gruebel:

OregonGhost 27. Sep 2007 21:49

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Wo sonst sollen sich die CodeGear-Leute auch ihre Delphi-Tricks holen, wenn nicht in der Delphi-PRAXiS :mrgreen:

Nils_13 28. Sep 2007 14:36

Re: Dateigröße ohne Öffnen der Datei berechnen
 
Hast du mal ein Aufrufbeispiel dafür ? Ich bin gerade echt zu blöd dafür :stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:24 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