File size calculation, Int64, and differences between 32bit and 64bit

后端 未结 5 1718
走了就别回头了
走了就别回头了 2021-01-19 06:27

I had problems with the following code:

var
  FileSize : Int64;
...
FileSize := Info.nFileSizeLow or (Info.nFileSizeHigh shl 32);

I expecte

5条回答
  •  时光取名叫无心
    2021-01-19 07:07

    First of all FileSize must be defined as UInt64 and not Int64...

    UInt64 (not available in early Delphi versions) is an unsigned 64 bit integer, aka a QWORD. This is the expected type for the FileSize (you won't expect a negative file size, won't you?).

    IMHO you could have coded - using UInt64 because we don't want to have some values reported as negative:

    FileSize := UInt64(Info.nFileSizeLow) or (UInt64(Info.nFileSizeHigh) shl 32));
    

    But under Delphi 7 it produces the same exact code as yours.

    FileSize := Info.nFileSizeLow or (Int64(Info.nFileSizeHigh) shl 32));
    

    So there is perhaps some compiler regression. Could you take a look at the asm generated code (step debugger then Alt+F2), and see if there is a difference. But it's unlikely...

    In all cases, here is a better (and faster) code:

    with Int64Rec(FileSize) do
    begin
      Lo := Info.nFileSizeLow;
      Hi := Info.nFileSizeHigh;
    end;
    

    The official MSDN documentation states about the WIN32_FIND_DATA Structure:

    nFileSizeHigh: The high-order DWORD value of the file size, in bytes.

    This value is zero unless the file size is greater than MAXDWORD.

    The size of the file is equal to (nFileSizeHigh * (MAXDWORD+1)) + nFileSizeLow.

    nFileSizeLow: The low-order DWORD value of the file size, in bytes.

    Here is the resulting code:

    FileSize := UInt64(Info.nFileSizeLow)+(UInt64(Info.nFileSizeHigh)*UInt64(1 shl 32));
    

    Quite a funny definition, indeed...

提交回复
热议问题