Yesterday I got a suggestion for a better implementation for TFile.Size from Stefan Glienke. Many thanks for it, Stefan.
In order to make the code compatible to other functions in System.IOUtils, I modified it in the way that I’m raising an EInOutError if there is a problem.
I could compile the code for all platforms Win32, Win64, MacOS32, iOS32, iOS64, Android32 and Linux64.
unit System.IOUtils.Helper;
interface
uses
System.IOUtils;
type
TFileHelper = record Helper for TFile
public
class function Size(const APath: string): Int64; static;
end;
implementation
{$IFDEF MSWINDOWS}
uses
System.SysUtils, Winapi.Windows;
{$ENDIF}
{$IFDEF POSIX}
uses
System.SysUtils, Posix.SysStat;
{$ENDIF}
{ TFileHelper }
class function TFileHelper.Size(const APath: string): Int64;
{$IFDEF MSWINDOWS}
var
lAttributes: TWin32FileAttributeData;
begin
if GetFileAttributesEx(PChar(APath), GetFileExInfoStandard, @lAttributes) then
begin
Int64Rec(Result).Lo := lAttributes.nFileSizeLow;
Int64Rec(Result).Hi := lAttributes.nFileSizeHigh;
end
else
raise EInOutError.Create(SysErrorMessage(GetLastError));
end;
{$ENDIF}
{$IFDEF POSIX}
var
lStat: _stat;
lFileName: Pointer;
lMarshaller: TMarshaller;
lError: Integer;
begin
lFileName := lMarshaller.AsAnsi(APath, CP_UTF8).ToPointer;
lError := stat(lFileName, lStat);
if lError = 0 then
Result := lStat.st_size
else
raise EInOutError.Create(SysErrorMessage(lError));
end;
{$ENDIF}
end.



