Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Dateigröße ermitteln ohne Datei zu öffnen (https://www.delphipraxis.net/64563-dateigroesse-ermitteln-ohne-datei-zu-oeffnen.html)

robinWie 5. Mär 2006 10:54


Dateigröße ermitteln ohne Datei zu öffnen
 
Hi,

ich suche die möglichkeit die Dateigröße zu ermitteln ohne die Datei zu öffnen.
In der Suche habe ich nichts gefunden und ich kenne bislang nur diese möglichkeit

Delphi-Quellcode:
var F: File
begin
 Assign(F,FileListBox1.FileName);
 Reset(F);
 Label1.Caption:=IntToStr(FileSize(F));
 ...
end;

marabu 5. Mär 2006 11:05

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Hallo Robin,

so könnte das funktionieren:

Delphi-Quellcode:
function FileSize(fn: TFileName): Int64;
var
  sr: TSearchRec;
begin
  if FindFirst(fn, faArchive, sr) = 0 then
  begin
    with sr.FindData do
      Result := nFileSizeHigh shl 32 + nFileSizeLow;
    FindClose(sr);
  end;
end;
Grüße vom marabu

Hawkeye219 5. Mär 2006 11:56

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zwei kleine Korrekturen:

1.) Falls die Datei nicht existiert, ist das Funktionsergebnis undefiniert.
2.) Das Schieben eines 32-Bit-Wertes um 32 Bits nach links löscht eigentlich nur den Wert. :wink:

Mein Vorschlag:

Delphi-Quellcode:
function FileSize(fn: TFileName): Int64;
var
  sr: TSearchRec;
begin
  if FindFirst(fn, faArchive, sr) = 0 then
  begin
    with sr.FindData do
      Result := Int64(nFileSizeHigh) shl 32 + nFileSizeLow;
    FindClose(sr);
  end
  else
    Result := 0;
end;

DP-Maintenance 5. Mär 2006 11:59

DP-Maintenance
 
Dieses Thema wurde von "Sharky" von "VCL / WinForms / Controls" nach "Object-Pascal / Delphi-Language" verschoben.
Ist hier besser aufgehoben.

marabu 5. Mär 2006 12:38

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Danke für das Korrekturlesen. Als Result verwende ich dann lieber -1, da 0 eine legitime Größe für eine existierende Datei ist.

Schönes Wochenende

marabu

Hawkeye219 5. Mär 2006 13:03

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Stimmt, so ist's besser :thumb:

Gruß,

Hawkeye

Luckie 5. Mär 2006 13:31

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Meine Version:
Delphi-Quellcode:
function GetFileSize(szFile: PChar): Int64;
var
  fFile            : THandle;
  wfd              : TWIN32FINDDATA;
begin
  result := 0;
  if not FileExists(szFile) then exit;
  fFile := FindFirstfile(pchar(szFile), wfd);
  if fFile = INVALID_HANDLE_VALUE then exit;
  result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  windows.FindClose(fFile);
end;

marabu 5. Mär 2006 14:04

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Hallo Michael, du non-VCL-Fetischist,

wenn du FileExists() raus nimmst und Result mit -1 initialisierst (siehe oben), dann nenne ich deinen Code elegant.

Freundliche Grüße vom marabu

Daniel G 5. Mär 2006 14:08

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zitat:

Zitat von marabu
wenn du FileExists() raus nimmst

Erklärst du kurz, warum? Oder hat das mehr "ästhetische" Gründe? :mrgreen:

ichbins 5. Mär 2006 14:11

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
weil fileexists in der sysutils steht und die nicht nonVCL-kompatibel ist ;)

marabu 5. Mär 2006 14:13

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Hallo Daniel,

wer die Implementierung von FileExists() kennt, der weiß, dass alle Sparversuche in diesem Code von Michael durch diesen einen Befehl wieder zunichte gemacht werden. Da ist dann mein VCL-Code noch sparsamer. FileExists() arbeitet intern mit FileAge() und dieses wiederum mit einem eigenen FindFirst-FindClose-Zyklus. Und außerdem wird die Prüfung von FindFirstFile() intern mit erledigt und das Ergebnis über den Rückgabewert signalisiert.

marabu

Daniel G 5. Mär 2006 14:25

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zitat:

Zitat von marabu
FileExists() arbeitet intern mit FileAge() und dieses wiederum mit einem eigenen FindFirst-FindClose-Zyklus. Und außerdem wird die Prüfung von FindFirstFile() intern mit erledigt und das Ergebnis über den Rückgabewert signalisiert.

Ah, ok. Bei der PE sind die Sourcen ja nicht mit dabei, daher hatte ich auch keine Chance, mir das genauer anzusehen.

Flocke 5. Mär 2006 14:34

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Aber dann sollte man noch mit den Attributen in der FINDDATA-Struktur überprüfen, ob es sich wirklich um eine Datei handelt (und nicht um ein Verzeichnis o.ä.)

Luckie 5. Mär 2006 20:36

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Ups, das gehört noch dazu:
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// Procedure : FileExists
// Comment  : -

function FileExists(const FileName: string; dir: boolean = false): Boolean;
var
  hidate, lodate   : word;
  Handle           : THandle;
  FindData         : TWin32FindData;
  LocalFileTime    : TFileTime;

type
  LongRec = packed record
    Lo, Hi: Word;
  end;

  function SubFileExists: Boolean;
  begin
    FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
    result := FileTimeToDosDateTime(LocalFileTime, HiDate, LoDate);
  end;
begin
  result := false;
  Handle := FindFirstFile(PChar(FileName), FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    case dir of
      TRUE: if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then result := SubFileExists;
      FALSE: if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then result := SubFileExists;
    end;
  end;
end;

Flocke 5. Mär 2006 21:51

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Durch das FileExists rufst du so zwei mal hintereinander FindFirstFile für dieselbe Datei auf - du musst doch in GetFileSize nach dem FindFirstFile einfach nur noch auf FILE_ATTRIBUTE_DIRECTORY testen.
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;
  if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then exit;
  result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  windows.FindClose(fFile);
end;

Hawkeye219 5. Mär 2006 22:12

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
...aber dabei keine neuen Speicherlöcher erzeugen! :zwinker:

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;
  if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  windows.FindClose(fFile);
end;
Gruß Hawkeye

Luckie 5. Mär 2006 22:25

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Wo war bei Flocke das Speicherleck?

@Flocke: Die Routinen sind schon etwas älter und hab esie lange nicht gebraucht, deswegen habe ich sie mir schon lange nicht mehr angeguckt. ;)

Matze 5. Mär 2006 22:38

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zitat:

Zitat von Luckie
Wo war bei Flocke das Speicherleck?

Nach FindFirstFile sollte immer ein FindClose folgen, was bei Flocke aufgrund des exits nicht mehr ausgeführt werden würde. Ich denke, das meinte Hawkeye.

Luckie 5. Mär 2006 23:02

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zitat:

Zitat von Matze
Zitat:

Zitat von Luckie
Wo war bei Flocke das Speicherleck?

Nach FindFirstFile sollte immer ein FindClose folgen, was bei Flocke aufgrund des exits nicht mehr ausgeführt werden würde. Ich denke, das meinte Hawkeye.

Nein:
Zitat:

If the function succeeds, the return value is a search handle used in a subsequent call to FindNextFile or FindClose.
If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
Wenn sie fehlschlägt gibt es also kein Handle, das man schließen könnte. ;)

Matze 5. Mär 2006 23:05

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Ich dachte, ich hätte meinen Beitrag editiert und ein "(soweit ich weiß)" eingefügt, so klingt es, als sei ich fest davon überzeugt gewesen. :gruebel:

Zitat:

Zitat von Luckie
Wenn sie fehlschlägt gibt es also kein Handle, das man schließen könnte. ;)

Oh, wieder was gelernt, dann kann ich auch kein Speicherleck erkennen. Thx für die Info, werde ich mir merken. :)

Luckie 5. Mär 2006 23:07

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Ups. Du hattes dich selber noch mal zitiert anstatt zu editieren. Und den habe ich gelöscht ohne ihn genau zu lesen. :oops:

Hawkeye219 5. Mär 2006 23:13

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
In der ersten if-Anweisung wird die Routine verlassen, falls FindFirstFile fehlschlägt. In diesem Fall muß nichts freigegeben werden.

Die letzte if-Anweisung wird meiner Meinung nach nur ausgeführt, wenn FindFirstFile nicht fehlschlägt. In diesem Fall sollte das Handle doch wieder freigegeben werden, oder sehe ich das falsch? :gruebel:

Luckie 5. Mär 2006 23:15

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Wird es ja auch. Mit result verläßt man ja die Routine nicht.

Hawkeye219 5. Mär 2006 23:28

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Stimmt, das war ja genau mein Vorschlag (Beitrag #16)!
Im Code von Flocke (Beitrag #15) stand vor der Zuweisung zu Result ein bedingtes Exit.
Damit wurde die Routine im Erfolgsfall verlassen, ohne das Handle freizugeben.

Luckie 5. Mär 2006 23:31

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Upps. Dieser kleine Unterschied ist mir entgangen. ;)

Flocke 6. Mär 2006 06:31

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zitat:

Zitat von Hawkeye219
...aber dabei keine neuen Speicherlöcher erzeugen! :zwinker:

Ui, stimmt :stupid:

Beim Umformatieren für das Posting war das FindClose wieder nach unten gerutscht (das hatte ich eigentlich direkt nach dem Test auf INVALID_HANDLE_VALUE).

danku 30. Apr 2006 13:42

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
hab ein problemchen:

ich will die files aus einem opendialog1 in die 2.spalte einer stringgrid bekommen:
my try:

Delphi-Quellcode:
...
 //Füllen der StringGrid mit Opendialog1Daten
   sgfiles.RowCount := OpenDialog1.Files.Count + 1;

   for i := 0 to OpenDialog1.Files.Count - 1 do
     begin
     sgfiles.cells[0,1 + i]:= OpenDialog1.Files[i];
     filesize(OpenDialog1.Files.Count - 1):=(sgfiles.cells[0,1+i]);

          end;
      end;
   end;

///////////////////////////////////////////////////////////

function Tfmformat.FileSize(fn: TFileName): Int64;
var
  sr: TSearchRec;
  i:byte;
begin
  if FindFirst(fn, faArchive, sr) = 0 then
  begin
    with sr.FindData do
      Result := Int64(nFileSizeHigh) shl 32 + nFileSizeLow;
    FindClose(sr);

   { else
    Result := 0; }
end;
end;

///////////////////////////////////////////////////////////

danku 2. Mai 2006 14:27

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
beziehe mich auf diese site:
http://www.swissdelphicenter.ch/de/showcode.php?id=149

auzug aus meinen code:
Delphi-Quellcode:
...
//MP3
sgfiles.cells[0,1 + i]:= OpenDialog1.Files[i];

//Größe der MP3
sgfiles.cells[1,1+i] := floattostr(GetDirSize(opendialog1.Files.Strings[i],true));
wie kann ich erreichen, das genau von der datei aus sgfiles.cells[0,1 + i] die größe in sgfiles.cells[1,1 + i] geschrieben wird?

jim_raynor 2. Mai 2006 14:41

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Und wo ist dein Problem? Ich kann bei dein Code im Letzten Beitrag sieht soweit gut aus. Du musst nur statt GetDirSize FileSize nutzen ...

danku 2. Mai 2006 14:54

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
:gruebel: hm ... habsch ein bissel gepennt :stupid: :cyclops:

kann man bei einer Tstringgrid die option "goediting" unterschiedliche auf 2spalten anwenden? die 1 true die andere false, oder gilt das komplett?

jim_raynor 2. Mai 2006 15:50

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Zitat:

Zitat von danku
kann man bei einer Tstringgrid die option "goediting" unterschiedliche auf 2spalten anwenden? die 1 true die andere false, oder gilt das komplett?

Was hat das denn mit der Frage:

Zitat:

Zitat von danku
wie kann ich erreichen, das genau von der datei aus sgfiles.cells[0,1 + i] die größe in sgfiles.cells[1,1 + i] geschrieben wird?

zu tuen?

Vielleicht stehe ich ja auch auf dem Schlauch :stupid:

Zeig am besten mal, wie du dein Stringgrid füllst und zwar komplett!

Edit: Naja solangsam verstehe ich: So ist es richtig.

Delphi-Quellcode:
for i := 0 to OpenDialog1.Files.Count - 1 do
begin
  sgfiles.cells[0,1 + i]:= OpenDialog1.Files[i];
  sgfiles.cells[1,1+i] := floattostr(filesize(opendialog1.Files.Strings[i]));
end;

danku 2. Mai 2006 18:15

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
:roll:

Delphi-Quellcode:
I-------------I-------------I
I Spalte 1    I   Spalte 2 I
I---------------------------I
I            I            I
I    ...    I   ...     I
I            I            I

Die Daten in Spalte1 soll man editieren können, in der 2 aber nicht.
Geht das üeberhaupt?

with tstringgrid do
.... gehts z.b. schon mal nicht

Rob09 15. Aug 2007 10:23

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Hi! Meine erste Frage: Ich würde gerne den Code aus Beitrag #16 benutzen. Wenn ich ihn allerdings folgendermaßen versuche aufzurufen

Delphi-Quellcode:
var
vTmp1:pchar;
vTmp2:int64;

begin
vTmp1:=pchar('c:test.bmp');
vTmp2:=getfilesize(vTmp1);
bekomme ich die letzte Zeile markiert mit "Incompatible Types: Cardinal and PChar". Wo liegt der Fehler?

Zweitens: Wo liegt der Vorteil von Hawkeyes Methode gegenüber diesem Prinzip:

Delphi-Quellcode:
var
f: file of byte;
v: integer;

begin
assignfile(f, 'c:\test'); reset(f);
v:=filesize(f);
closefile(f);
Danke schonmal!
Gruß! Robert

Hawkeye219 15. Aug 2007 16:53

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Herzlich willkommen in der Delphi-PRAXiS, Robert!

Den von dir beschriebenen Fehler kann ich nicht nachvollziehen. Ist das wirklich der Quelltext, der den Fehler auslöst?

Zitat:

Zitat von Rob09
Wo liegt der Vorteil von Hawkeyes Methode[...]

Du schmückst mich mit fremden Federn, die Routine stammt von Luckie (Beitrag #7). Wir haben sie nur im Laufe des Threads ein wenig weiterentwickelt.

Deine Frage wird zum Teil schon durch den Thread-Titel beantwortet: der Code liefert die Größe einer Datei, ohne diese Datei wirklich zu öffnen. Ein weiterer Vorteil ist, daß die Routine auch bei Dateien ab 2 GByte Länge den richtigen Wert für die Größe ermittelt. Die Routinen der Delphi-RTL funktionieren (zumindest bis Version 7) in diesem Fall nicht.

Gruß Hawkeye

Rob09 15. Aug 2007 18:10

Re: Dateigröße ermitteln ohne Datei zu öffnen
 
Hi! Danke, bin sehr herzlich aufgenommen worden ;-)

Hmm... ja, den Fehler bekomme ich. Naja, hab das Prog jetzt halt mit FileSize() geschrieben. Ich nehme an, das (was im Thread-Titel steckt) bedeutet dann im Endeffekt, dass die Methode schneller ist als FileSize(), richtig?

LG!

MuTzE.Y85 9. Mai 2014 14:00

AW: Dateigröße ermitteln ohne Datei zu öffnen
 
Eigentlich kann man doch auch
Code:
function GetFileSize(szFile: String): Int64;
statt
Code:
function GetFileSize(szFile: PChar): Int64;
schreiben, dann muss man beim Aufruf der Funktion nich auch noch zu PChar umwandeln. Ist ja doppelt gemoppelt :D

Eingabe String
Delphi-Quellcode:
function GetFileSize(szFile: String): Int64;
var
  fFile: THandle;
  wfd: TWIN32FINDDATA;
begin
  Result := -1;
  fFile := FindFirstfile(PChar(szFile), wfd);
  if fFile = INVALID_HANDLE_VALUE then Exit;
  if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    Result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  Windows.FindClose(fFile);
end;
Und wenn man PChar vorliegen hat, dann kann man sich die Konvertierung innerhalb der Funktion sparen :wink:

Eingabe PChar
Delphi-Quellcode:
function GetFileSize(szFile: PChar): Int64;
var
  fFile: THandle;
  wfd: TWIN32FINDDATA;
begin
  Result := -1;
  fFile := FindFirstfile(szFile, wfd);
  if fFile = INVALID_HANDLE_VALUE then Exit;
  if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    Result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  Windows.FindClose(fFile);
end;

hathor 9. Mai 2014 17:32

AW: Dateigröße ermitteln ohne Datei zu öffnen
 
Kleine Änderung für XE2:

Delphi-Quellcode:
function GetFileSize(szFile: String): Int64;
var
  fFile: THandle;
  wfd: TWIN32FINDDATA;
begin
  Result := -1;
  fFile := FindFirstfile(PChar(szFile), wfd);
  if fFile = INVALID_HANDLE_VALUE then Exit;
  if (wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    Result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
  WinApi.Windows.FindClose(fFile); //               <---------------------
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:53 Uhr.

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