调用 FileRead 后的奇怪计数值
Strange Count value after calling FileRead
我正在尝试将读取的字节数与传递给 FileRead which is a wrapper around the WinAPi ReadFile 函数的计数进行比较。
问题是我根据 ReadFromFile
过程的结构得到了不同的值(added/subtracted 行的 none 更改了计数变量)。
如果你运行下面的代码你会得到这个输出
FileHandle: 400
SizeOfFile: 8672
Current position: 8655
aCount before SetLength: 17
aCount before FileRead: 17
Number of bytes read: 17
aCount after FileRead: 2200
EAccessViolation: Access violation at address 0040C5BC in module 'Project7.exe'. Read of address C23C30BA
AV 是因为编译器在范围末尾释放了动态数组(并非总是如此)。
正如您在 FileRead 之后看到的 count == 2200
(在此之前我得到了 0)。如果您注释掉第二个 API 呼叫或第二行,则计数是正确的
你能告诉我这是什么吗?我该如何解决?
program Project7;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, WinAPI.Windows, System.Classes;
procedure ReadFromFile(aFileHandle: THandle; aCount: Longint);
var
aPosition, ReadRes: Int64;
TmpBuffer: TBytes;
begin
writeln('aCount before SetLength: ',aCount);
SetLength(TmpBuffer, aCount);
writeln('aCount before FileRead: ',aCount);
ReadRes := FileRead(aFileHandle, TmpBuffer, aCount);
Writeln('Number of bytes read: ', ReadRes);
//aPosition := FileSeek(aFileHandle, 0, Ord(soCurrent)); // second API call
//Writeln('Current position after read: ', aPosition); // line two
writeln('aCount after FileRead: ',aCount);
if ReadRes <> aCount then
//Raise Exception.Create('hi there');
// DoWrite(TmpBuffer[0], aCount);
end;
var
FFileHandle: THandle;
aFileName: string;
I1: Integer;
aFilePhysicalSize: Int64;
FPosition: Int64;
begin
try
aFileName := 'C:\Users\nacereddine\Desktop\ascii-table.gif';
{ TODO -oUser -cConsole Main : Insert code here }
FFileHandle := CreateFile(PChar(aFileName), GENERIC_READ,
FILE_SHARE_READ, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
Writeln('FileHandle: ', FFileHandle);
aFilePhysicalSize := FileSeek(FFileHandle, 0 , Ord(soEnd));
Writeln('SizeOfFile: ', aFilePhysicalSize);
FPosition := FileSeek(FFileHandle, aFilePhysicalSize - 17 , Ord(soBeginning));
Writeln('Current position: ', FPosition);
I1 := 17;
ReadFromFile(FFileHandle, I1);
readln;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
readln;
end;
end;
end.
您在此处使用的过程版本 fileread
具有未类型化的第二个参数:
TmpBuffer: TBytes;
...
ReadRes := FileRead(aFileHandle, TmpBuffer, aCount);
但在这种情况下,您应该取消引用动态数组,例如 TmpBuffer[0]
来自您的帮助link:
//this version is used
function FileRead(Handle: THandle; var Buffer; Count: LongWord): Integer;
//perhaps you wanted that one:
function FileRead(Handle: THandle; var Buffer: TBytes; Offset, Count: LongWord): Integer;
我正在尝试将读取的字节数与传递给 FileRead which is a wrapper around the WinAPi ReadFile 函数的计数进行比较。
问题是我根据 ReadFromFile
过程的结构得到了不同的值(added/subtracted 行的 none 更改了计数变量)。
如果你运行下面的代码你会得到这个输出
FileHandle: 400
SizeOfFile: 8672
Current position: 8655
aCount before SetLength: 17
aCount before FileRead: 17
Number of bytes read: 17
aCount after FileRead: 2200
EAccessViolation: Access violation at address 0040C5BC in module 'Project7.exe'. Read of address C23C30BA
AV 是因为编译器在范围末尾释放了动态数组(并非总是如此)。
正如您在 FileRead 之后看到的 count == 2200
(在此之前我得到了 0)。如果您注释掉第二个 API 呼叫或第二行,则计数是正确的
你能告诉我这是什么吗?我该如何解决?
program Project7;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, WinAPI.Windows, System.Classes;
procedure ReadFromFile(aFileHandle: THandle; aCount: Longint);
var
aPosition, ReadRes: Int64;
TmpBuffer: TBytes;
begin
writeln('aCount before SetLength: ',aCount);
SetLength(TmpBuffer, aCount);
writeln('aCount before FileRead: ',aCount);
ReadRes := FileRead(aFileHandle, TmpBuffer, aCount);
Writeln('Number of bytes read: ', ReadRes);
//aPosition := FileSeek(aFileHandle, 0, Ord(soCurrent)); // second API call
//Writeln('Current position after read: ', aPosition); // line two
writeln('aCount after FileRead: ',aCount);
if ReadRes <> aCount then
//Raise Exception.Create('hi there');
// DoWrite(TmpBuffer[0], aCount);
end;
var
FFileHandle: THandle;
aFileName: string;
I1: Integer;
aFilePhysicalSize: Int64;
FPosition: Int64;
begin
try
aFileName := 'C:\Users\nacereddine\Desktop\ascii-table.gif';
{ TODO -oUser -cConsole Main : Insert code here }
FFileHandle := CreateFile(PChar(aFileName), GENERIC_READ,
FILE_SHARE_READ, nil, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
Writeln('FileHandle: ', FFileHandle);
aFilePhysicalSize := FileSeek(FFileHandle, 0 , Ord(soEnd));
Writeln('SizeOfFile: ', aFilePhysicalSize);
FPosition := FileSeek(FFileHandle, aFilePhysicalSize - 17 , Ord(soBeginning));
Writeln('Current position: ', FPosition);
I1 := 17;
ReadFromFile(FFileHandle, I1);
readln;
except
on E: Exception do
begin
Writeln(E.ClassName, ': ', E.Message);
readln;
end;
end;
end.
您在此处使用的过程版本 fileread
具有未类型化的第二个参数:
TmpBuffer: TBytes;
...
ReadRes := FileRead(aFileHandle, TmpBuffer, aCount);
但在这种情况下,您应该取消引用动态数组,例如 TmpBuffer[0]
来自您的帮助link:
//this version is used
function FileRead(Handle: THandle; var Buffer; Count: LongWord): Integer;
//perhaps you wanted that one:
function FileRead(Handle: THandle; var Buffer: TBytes; Offset, Count: LongWord): Integer;