我正在尝试使用来自vincenzo.net的ISXKB的公共域代码返回文件的大小。
protected void FILL_DATA (object sender, EventArgs e)
{
DataTable IACS = new DataTable ();
IACS = GenerateTransposedTableinCsharp (generateIacs ());
for (int i = 6; i <= 8; i++) {
string rowText = "A0" + i; // this gets updated for each outer iteration
for (int j = 1; j <= 14; j++) {
string text = rowText + j; // text is now in the form A0XJ
// convert string to object id
}
}
}
但是,这似乎无法正常工作并返回function CloseHandle (hHandle: THandle): Boolean;
external 'CloseHandle@kernel32.dll stdcall';
const
// Some constants for CreateFile ().
GENERIC_READ = $80000000;
GENERIC_WRITE = $40000000;
GENERIC_EXECUTE = $20000000;
GENERIC_ALL = $10000000;
FILE_SHARE_READ = 1;
FILE_SHARE_WRITE = 2;
FILE_SHARE_DELETE = 4;
CREATE_NEW = 1;
CREATE_ALWAYS = 2;
OPEN_EXISTING = 3;
OPEN_ALWAYS = 4;
TRUNCATE_EXISTING = 5;
FILE_READ_ATTRIBUTES = $80;
FILE_WRITE_ATTRIBUTES = $100;
// General Win32.
INVALID_HANDLE_VALUE = -1;
function CreateFile (
lpFileName : String;
dwDesiredAccess : Cardinal;
dwShareMode : Cardinal;
lpSecurityAttributes : Cardinal;
dwCreationDisposition : Cardinal;
dwFlagsAndAttributes : Cardinal;
hTemplateFile : Integer
): Integer;
external 'CreateFileA@kernel32.dll stdcall';
function GetFileSize (hFile: THandle; var lpFileSizeHigh: Integer): Integer;
external 'GetFileSize@kernel32.dll stdcall';
function GetTheFileSize (FileName: String): Integer;
var
hFile: THandle;
iSize: Integer;
hSize: Integer;
begin
hFile := CreateFile (FileName,
GENERIC_READ,// Desired access.
FILE_SHARE_READ + FILE_SHARE_WRITE,
0, // Security attributes.
OPEN_EXISTING,
FILE_ATTRIBUTE_TEMPORARY,
0);
if (INVALID_HANDLE_VALUE = hFile) then
begin
Result := 0;
Exit;
end;
iSize := GetFileSize (hFile, hSize);
CloseHandle (hFile);
Result := iSize;
end;
,我认为这是因为它正在0
退出。我传递给它的文件存在且可访问。任何人都可以解释为什么这是失败或建议替代方法?请注意,我无法使用内置的if (INVALID_HANDLE_VALUE = hFile) then Result := 0
函数,因为它有2GB的限制,这对我的目的来说还不够。
答案 0 :(得分:1)
我假设你使用的是Inno Setup的Unicode版本。
因此,您必须使用CreateFile
的Unicode版本,CreateFileW
,而不是CreateFileA
:
external 'CreateFileW@kernel32.dll stdcall';
无论如何,ISXKB implementation也有2 GB的限制:
此声明适用于最高2 GB 的文件 ...
...以整数形式检索文件大小的低32位部分,然后再次关闭文件。
要支持64位大小,请将其更改为:
function GetTheFileSize (FileName: String): Int64;
...
begin
...
Result := Int64(Cardinal(iSize)) + (Int64(Cardinal(hSize)) shl 32);
end;
无论如何,这有点矫枉过正。并且正如您发现如果另一个应用程序打开文件而不允许其他应用程序至少读取该文件(它在FILE_SHARE_READ
的调用中未指定CreateFile
)它不起作用。
请注意,FileSize
在这种情况下不会起作用,因为它与ISXKB的GetTheFileSize
基本相同。
function GetTheFileSize(FileName: String): Int64;
var
FindRec: TFindRec;
begin
if FindFirst(FileName, FindRec) then
begin
Result := Int64(FindRec.SizeHigh) shl 32 + FindRec.SizeLow;
FindClose(FindRec);
end
else
begin
Result := -1;
end;
end;