Delphi 2010 has a nice set of new file access functions in IOUtils.pas
(I especially like the UTC versions of the date-related functions). What I miss so far is something like
TFile.GetSize (const Path : String)
What is the Delphi 2010-way to get the size of a file? Do I have to go back and use FindFirst to access TSearchRec.FindData
?
Thanks.
In Delphi code, call FileSize to determine the size of the file specified by the file variable F. The size is expressed as the number of records in a record file. Thus: If the file is declared as a file of byte, then the record size defaults to one byte, and FileSize returns the number of bytes in the file.
Locate the file or folder whose size you would like to view. Click the file or folder. Press Command + I on your keyboard. A window opens and shows the size of the file or folder.
Explanation: The function filesize() returns the size of the specified file and it returns the file size in bytes on success or FALSE on failure.
I'm not sure if there's a "Delphi 2010" way, but there is a Windows way that doesn't involve FindFirst and all that jazz.
I threw together this Delphi conversion of that routine (and in the process modified it to handle > 4GB size files, should you need that).
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;
You could actually just use GetFileSize() but this requires a file HANDLE, not just a file name, and similar to the GetCompressedFileSize() suggestion, this requires two variables to call. Both GetFileSize() and GetCompressedFileSize() overload their return value, so testing for success and ensuring a valid result is just that little bit more awkward.
GetFileSizeEx() avoids the nitty gritty of handling > 4GB file sizes and detecting valid results, but also requires a file HANDLE, rather than a name, and (as of Delphi 2009 at least, I haven't checked 2010) isn't declared for you in the VCL anywhere, you would have to provide your own import declaration.
Using an Indy unit:
uses IdGlobalProtocols; function FileSizeByName(const AFilename: TIdFileName): Int64;
You can also use DSiFileSize from DSiWin32. Works in "all" Delphis. Internally it calls CreateFile and 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 }
I'd like to mention few Pure Delphi ways. Though i think Deltics made a most speed-effective answer for Windows platform, yet sometimes you want just rely on RTL and also make portable code that would work in Delphi for MacOS or in FreePascal/Virtual Pascal/whatever.
There is FileSize
function left from Turbo Pascal days.
The sample above lacks "read-only" mode setting. You would require that to open r/o file such as one on CD-ROM media or in folder with ACLs set to r/o. Before calling ReSet
there should be zero assigned to FileMode
global var.
It would not work on files above 2GB size (maybe with negative to cardinal cast - up to 4GB) but is "out of the box" one.
There is one more approach, that you may be familiar if you ever did ASM programming for MS-DOS. You Seek
file pointer to 1st byte, then to last byte, and check the difference.
I can't say exactly which Delphi version introduced those, but i think it was already in some ancient version like D5 or D7, though that is just common sense and i cannot check it.
That would take you an extra THandle variable and try-finally
block to always close the handle after size was obtained.
Aside from 1st approach this is int64-capable. It is also compatible with FreePascal, though with some limitations
You can also create and use TFileStream
-typed object - which was the primary, officially blessed avenue for file operations since Delphi 1.0
As a side note, this avenue is of course integrated with aforementioned IOUtils
unit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With