简体   繁体   中英

Delphi fastest FileSize for sizes > 10gb

Wanted to check with you experts if there are any drawbacks in this funtion. Will it work properly on the various Windows OS? I am using Delphi Seattle (32 and 64 bit exe's). I am using this instead of Findfirst for its speed.

function GetFileDetailsFromAttr(pFileName:WideString):int64;
var
  wfad: TWin32FileAttributeData;
  wSize:LARGE_INTEGER ;
begin
  Result:=0 ;
  if not GetFileAttributesEx(pwidechar(pFileName), GetFileExInfoStandard,@wfad) then
    exit;

  wSize.HighPart:=wfad.nFileSizeHigh ;
  wSize.LowPart:=wfad.nFileSizeLow  ;
  result:=wsize.QuadPart ;
end;

The typical googled samples shown with this command does not work for filesize > 9GB

function GetFileAttributesEx():Int64 using 
begin
...
  result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))

Code with variant record is correct.

But this code

result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))

is just wrong, result cannot overcome 32-bit border

Code from link in comment

result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);

is wrong because it does not account how compiler works with 32 and 64-bit values. Look at the next example showing how to treat this situation properly (for value d, e):

var
  a, b: DWord;
  c, d, e: Int64;
  wSize:LARGE_INTEGER ;
begin
  a := 1;
  b := 1;
  c := Int64(a) or Int64(b shl 32);
  d := Int64(a) or Int64(b) shl 32;
  wSize.LowPart := a;
  wSize.HighPart := b;
  e := wsize.QuadPart;
  Caption := Format('$%x $%x  $%x', [c, d, e]);

Note that in the expression for c 32-bit value is shifted by 32 bits left and looses set bit, then zero transforms to 64-bit.

Unbound to how you get the filesize: it would even be faster if you'd use a type ( manual ) that exists for ~25 years already to assign the filesize directly to the function's result instead of using an intermediate variable:

  Int64Rec(result).Hi:= wfad.nFileSizeHigh;
  Int64Rec(result).Lo:= wfad.nFileSizeLow;
end;

In case this isn't obvious to anyone here's what the compilation looks like:

带中间变量

Above: the intermediate variable w: LARGE_INTEGER first gets assigned the two 32bit parts and then is assigned itself to the function's result. Cost: 10 instructions.

直接在函数结果上使用记录

Above: the record Int64Rec is used to cast the function's result and assign both 32bit parts directly, without the need of any other variable. Cost: 6 instructions.

Environment used: Delphi 7.0 (Build 8.1), compiler version 15.0, Win32 executable, code optimization: on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM