Erste Größe einer Datei in Delphi 2010 oder später?
-
10-07-2019 - |
Frage
Delphi 2010 hat eine schöne Reihe von neuen Dateizugriffsfunktionen in IOUtils.pas
(Besonders gut gefällt mir die UTC-Versionen der datumsbezogenen Funktionen). Was ich vermisse, ist so weit so etwas wie
TFile.GetSize (const Path : String)
Was ist die Delphi 2010-Weg, um die Größe einer Datei zu bekommen? Muss ich zurück gehen und verwenden Findfirst TSearchRec.FindData
zugreifen?
Danke.
Lösung
Ich bin nicht sicher, ob eine "Delphi 2010" Art und Weise gibt es, aber es gibt ein Windows-Art und Weise, die nicht Findfirst mit sich bringt und alle, den Jazz .
Ich warf zusammen, um diese Delphi Umwandlung dieser Routine (und in dem Prozess geändert, es zu handhaben> 4 GB Größe Dateien, sollen Sie müssen das).
uses
WinApi.Windows;
function FileSize(const aFilename: String): Int64;
var
info: TWin32FileAttributeData;
begin
result := -1;
if NOT GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then
EXIT;
result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;
Sie können tatsächlich nutzen nur GetFileSize () , aber dies erfordert eine Datei-Handelte, nicht nur einen Dateinamen, und ähnlich den GetCompressedFileSize () Vorschlag erfordert dies zwei Variablen zu nennen. Sowohl GetFileSize () und GetCompressedFileSize () überlastete ihren Rückgabewert, so dass für den Erfolg zu testen und ein gültiges Ergebnis zu gewährleisten ist nur ein bisschen mehr umständlich.
GetFileSize Ex () vermeidet die Nitty Gritty der Handhabung> 4 GB Dateigrößen und valide Ergebnisse zu erfassen, sondern erfordert auch eine Datei-Handelte, anstatt einen Namen, und ( wie von Delphi 2009 zumindest habe ich 2010 nicht geprüft) wird überall in der VCL für Sie nicht erklärt, würden Sie haben Ihre eigene Einfuhranmeldung zur Verfügung zu stellen.
Andere Tipps
eine Indy-Einheit verwenden:
uses IdGlobalProtocols;
function FileSizeByName(const AFilename: TIdFileName): Int64;
Sie können auch DSiFileSize von DSiWin32 verwenden. Arbeitet in "alle" Delphis. Intern ruft Createfile und GetFileSize.
function DSiFileSize(const fileName: string): int64;
var
fHandle: DWORD;
begin
fHandle := CreateFile(PChar(fileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if fHandle = INVALID_HANDLE_VALUE then
Result := -1
else try
Int64Rec(Result).Lo := GetFileSize(fHandle, @Int64Rec(Result).Hi);
finally CloseHandle(fHandle); end;
end; { DSiFileSize }
Ich möchte einige Reine Delphi Möglichkeiten nennen. Obwohl ich denke, dass Deltics für eine geschwindigkeitsstabilste wirksame Antwort gemacht Windows-Plattform , aber manchmal möchte man einfach verlassen sich auf RTL und auch portablen Code machen, die Delphi funktionieren würde in für MacOS oder in Freepascal / Virtual Pascal / was auch immer .
Es gibt FileSize
Funktion von Pascal Tagen Turbo links.
- http://turbopascal.org/system-functions-filepos-and-filesize
- http://docwiki.embarcadero.com/CodeExamples/XE2 / en / SystemFileSize_ (Delphi)
- http://docwiki.embarcadero.com/Libraries/XE2/en /System.FileSize
Die Probe oben fehlt "read-only" Modus-Einstellung. Sie würde erfordern, dass r / o-Datei wie eine CD-ROM-Medien oder in Ordnern mit ACLs zu r / o gesetzt zu öffnen. Vor dem Aufruf von ReSet
sollte es Null global var FileMode
zugewiesen.
Es würde auf Dateien über 2 GB Größe nicht (vielleicht mit negativ Kardinal Besetzung - bis zu 4 GB). Aber ist „out of the box“ ein
Es gibt einen weiteren Ansatz, dass Sie vertraut sein, wenn Sie jemals ASM Programmierung für MS-DOS haben. Sie Seek
Dateizeiger auf 1. Byte, dann zum letzten Byte, und prüfen Sie den Unterschied.
Ich kann nicht genau sagen, was Delphi-Version diejenigen eingeführt, aber ich denke, es war schon in einigen alten Version wie D5 oder D7, obwohl das nur der gesunde Menschenverstand ist, und ich kann es nicht überprüfen.
Das würde nimmt Sie einen zusätzlichen THandle Variable und try-finally
Block immer den Griff schließt nach Größe erhalten wurde.
- Probe der Länge und solche bekommen
- http://docwiki.embarcadero.com/Libraries/XE2 /en/System.SysUtils.FileOpen
- http://docwiki.embarcadero.com/Libraries/XE2 /en/System.SysUtils.FileSeek
Neben ersten Ansatz ist dieses int64-fähig. Es ist auch kompatibel mit Freepascal, wenn auch mit einigen Einschränkungen
Sie können auch TFileStream
typisierte Objekt erstellen und verwenden - das war die primäre , offiziell gesegnet Allee für Datei-Operationen , da Delphi 1.0
- http://www.freepascal.org/docs -html / rtl / classes / tfilestream.create.html
- http://www.freepascal.org/docs -html / rtl / classes / tstream.size.html
- http://docwiki.embarcadero.com/Libraries /XE2/en/System.Classes.TFileStream.Create
- http://docwiki.embarcadero.com/Libraries / XE2 / en / System.Classes.TStream.Size
Als Randbemerkung, dieser Weg ist natürlich mit oben genannten IOUtils
Einheit integriert.
uses
System.Classes, System.IOUtils;
function GetFileSize(const FileName : string) : Int64;
var
Reader: TFileStream;
begin
Reader := TFile.OpenRead(FileName);
try
result := Reader.Size;
finally
Reader.Free;
end;
end;
Dies ist eine kurze Lösung Filesize verwenden, die den Job:
function GetFileSize(p_sFilePath : string) : Int64;
var
oFile : file of Byte;
begin
Result := -1;
AssignFile(oFile, p_sFilePath);
try
Reset(oFile);
Result := FileSize(oFile);
finally
CloseFile(oFile);
end;
end;
Von dem, was ich weiß, Filesize ist nur verfügbar, von XE2.