Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 调用FileRead后的奇怪计数值_Windows_Delphi_Winapi_Delphi 10 Seattle - Fatal编程技术网

Windows 调用FileRead后的奇怪计数值

Windows 调用FileRead后的奇怪计数值,windows,delphi,winapi,delphi-10-seattle,Windows,Delphi,Winapi,Delphi 10 Seattle,我试图将读取的字节数与传递给WinAPi函数包装器的计数进行比较 问题是,根据我的ReadFromFile过程的结构,我得到了不同的值(添加/减去的行都不会更改count变量) 如果您运行下面的代码,您将获得此输出 FileHandle: 400 SizeOfFile: 8672 Current position: 8655 aCount before SetLength: 17 aCount before FileRead: 17 Number of bytes read: 17 aCount

我试图将读取的字节数与传递给WinAPi函数包装器的计数进行比较

问题是,根据我的
ReadFromFile
过程的结构,我得到了不同的值(添加/减去的行都不会更改count变量)

如果您运行下面的代码,您将获得此输出

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是因为编译器在作用域末尾释放了动态数组(并不总是这样)。 正如您在文件读取后看到的那样,这里的
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.
程序项目7;
{$APPTYPE控制台}
{$R*.res}
使用
System.SysUtils、WinAPI.Windows、System.class;
过程ReadFromFile(文件句柄:THandle;帐户:Longint);
变量
位置,读取器:Int64;
TmpBuffer:t字节;
开始
writeln('SetLength之前的aCount:',aCount);
设置长度(TmpBuffer,aCount);
writeln('FileRead之前的帐户:',aCount);
ReadRes:=FileRead(文件句柄、TmpBuffer、aCount);
Writeln('读取的字节数:',ReadRes);
//位置:=FileSeek(文件句柄,0,Ord(soCurrent));//第二次API调用
//Writeln('读取后的当前位置:',位置);//第二行
writeln('FileRead之后的aCount:',aCount);
如果ReadRes是account那么
//引发异常。创建('hi there');
//DoWrite(TmpBuffer[0],一个账户);
结束;
变量
菲利汉德尔:坦德尔;
aFileName:string;
I1:整数;
aFilePhysicalSize:Int64;
位置:Int64;
开始
尝试
aFileName:=“C:\Users\nacereddine\Desktop\ascii table.gif”;
{TODO-oUser-cConsole Main:在此处插入代码}
FFileHandle:=CreateFile(PChar(aFileName),通用\u读取,
文件\u共享\u读取,无,打开\u现有,
文件\属性\正常,0);
Writeln('FileHandle:',FFileHandle);
aFilePhysicalSize:=FileSeek(FFileHandle,0,Ord(soEnd));
Writeln('SizeOfFile:',aFilePhysicalSize);
FPosition:=文件seek(FFileHandle,aFilePhysicalSize-17,Ord(soBeginning));
Writeln('当前位置:',FPosition);
I1:=17;
ReadFromFile(FFileHandle,I1);
readln;
除了
关于E:Exception-do
开始
Writeln(E.ClassName,“:”,E.Message);
readln;
结束;
结束;
结束。

您正在使用带有未键入的第二个参数的过程版本
fileread

TmpBuffer: TBytes;
...
ReadRes := FileRead(aFileHandle, TmpBuffer, aCount);
但在这种情况下,应该取消对动态数组的引用,如
TmpBuffer[0]

从您的帮助链接:

 //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;

啊,非类型参数。我讨厌那些。该功能现在运行良好。然而,我可以把我的行为描述为未定义的行为或什么。上一个操作系统错误为0,函数成功。操作系统调用可以在没有操作系统错误的情况下工作-句柄有效,地址属于内存空间,等等。。。您只需写入意外内存(AV可能会在稍后发生)