Delphi 最快的文件大小 > 10gb
Delphi fastest FileSize for sizes > 10gb
想请教各位高手,这个功能有没有什么缺点。它能在各种 Windows OS 上正常工作吗?我正在使用 Delphi Seattle(32 位和 64 位 exe)。我使用它而不是 Findfirst 是为了它的速度。
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;
使用此命令显示的典型谷歌示例不适用于文件大小 > 9GB
function GetFileAttributesEx():Int64 using
begin
...
result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))
不受文件大小获取方式的限制:如果您使用已经存在约 25 年的类型 (manual) 将文件大小直接分配给函数的结果而不是使用中间变量:
Int64Rec(result).Hi:= wfad.nFileSizeHigh;
Int64Rec(result).Lo:= wfad.nFileSizeLow;
end;
如果这对任何人来说都不是显而易见的,这里是编译的样子:
以上:中间变量 w: LARGE_INTEGER
首先被分配了两个 32 位部分,然后将其自身分配给函数的结果。成本:10 条指令。
上面:记录Int64Rec
用于转换函数的结果并直接分配两个32位部分,而不需要任何其他变量。成本:6 条指令。
使用的环境:Delphi7.0(Build 8.1),编译器版本 15.0,Win32 可执行文件,代码优化:on.
带有变体记录的代码是正确的。
但是这段代码
result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))
只是错误,结果无法克服32位边界
代码来自 link 评论
result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
是错误的,因为它没有说明编译器如何处理 32 位和 64 位值。查看下一个示例,展示如何正确处理这种情况(对于值 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]);
请注意,在 c
的表达式中,32 位值向左移动 32 位,并且 松散 设置位,然后将零转换为 64 位。
想请教各位高手,这个功能有没有什么缺点。它能在各种 Windows OS 上正常工作吗?我正在使用 Delphi Seattle(32 位和 64 位 exe)。我使用它而不是 Findfirst 是为了它的速度。
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;
使用此命令显示的典型谷歌示例不适用于文件大小 > 9GB
function GetFileAttributesEx():Int64 using
begin
...
result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))
不受文件大小获取方式的限制:如果您使用已经存在约 25 年的类型 (manual) 将文件大小直接分配给函数的结果而不是使用中间变量:
Int64Rec(result).Hi:= wfad.nFileSizeHigh;
Int64Rec(result).Lo:= wfad.nFileSizeLow;
end;
如果这对任何人来说都不是显而易见的,这里是编译的样子:
以上:中间变量 w: LARGE_INTEGER
首先被分配了两个 32 位部分,然后将其自身分配给函数的结果。成本:10 条指令。
上面:记录Int64Rec
用于转换函数的结果并直接分配两个32位部分,而不需要任何其他变量。成本:6 条指令。
使用的环境:Delphi7.0(Build 8.1),编译器版本 15.0,Win32 可执行文件,代码优化:on.
带有变体记录的代码是正确的。
但是这段代码
result:=((&wfad.nFileSizeHigh) or (&wfad.nFileSizeLow))
只是错误,结果无法克服32位边界
代码来自 link 评论
result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
是错误的,因为它没有说明编译器如何处理 32 位和 64 位值。查看下一个示例,展示如何正确处理这种情况(对于值 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]);
请注意,在 c
的表达式中,32 位值向左移动 32 位,并且 松散 设置位,然后将零转换为 64 位。