Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.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
Arrays 如何将Delphi中的文件读入字节数组?_Arrays_Delphi_Byte_Delphi Xe2 - Fatal编程技术网

Arrays 如何将Delphi中的文件读入字节数组?

Arrays 如何将Delphi中的文件读入字节数组?,arrays,delphi,byte,delphi-xe2,Arrays,Delphi,Byte,Delphi Xe2,我试图在Delphi XE2中将文件读入字节数组 这是我当前的代码: function FileToBytes(const AName: string; var Bytes: TBytes): Boolean; var Ms: TMemoryStream; begin Result := False; if not FileExists(AName) then Exit; Ms := TMemoryStream.Create; try Ms.LoadFromF

我试图在Delphi XE2中将文件读入字节数组

这是我当前的代码:

function FileToBytes(const AName: string; var Bytes: TBytes): Boolean;
var
  Ms: TMemoryStream;
begin
  Result := False;
  if not FileExists(AName) then
    Exit;
  Ms := TMemoryStream.Create;
  try
    Ms.LoadFromFile(AName);
    if Ms.Size > 0 then
    begin
      Ms.Position := 0;
      MS.ReadBuffer(Bytes[0], Ms.Size);
      Result := True;
    end;
  finally
    Ms.Free;
  end;
end;

procedure runFile();
var
  Bytes: TBytes;
  OpFile: String;
begin
  OpFile := 'C:\Users\Kenny\Documents\calc.exe';
  Bytes := nil;
  if FileToBytes(OpFile, Bytes) then
  begin
    //do someting with Bytes(array of Byte)

  end;
end;
我在这行遇到一个错误:

MS.ReadBuffer(Bytes[0], Ms.Size);
错误是:

0x00404727处的访问冲突:写入地址0x00000008


如果您能帮助解决此问题,我们将不胜感激。

您没有分配阵列,这就是错误的原因。您可以按如下方式修复代码:

Ms.LoadFromFile(AName);
SetLength(Bytes, Ms.Size);
Ms.Position := 0;
MS.ReadBuffer(Pointer(Bytes)^, Ms.Size);
Result := True;
function FileToBytes(const AName: string; var Bytes: TBytes): Boolean;
var
  Stream: TFileStream;
begin
  if not FileExists(AName) then
  begin
    Result := False;
    Exit;
  end;
  Stream := TFileStream.Create(AName, fmOpenRead);
  try
    SetLength(Bytes, Stream.Size);
    Stream.ReadBuffer(Pointer(Bytes)^, Stream.Size);
  finally
    Stream.Free;
  end;
  Result := True;
end;
请注意,我避免了检查零长度文件的需要,并使用了
指针(字节)
,以便在范围检查处于活动状态时代码可以工作

我还要指出,您的代码与我所说的Delphi内存流反模式不符。将文件读入内存流,内存流本质上是一个字节数组。然后从那个字节数组复制到另一个字节数组。将整个文件写入两个单独的字节数组。这比必要的多了一个。最好这样写:

Ms.LoadFromFile(AName);
SetLength(Bytes, Ms.Size);
Ms.Position := 0;
MS.ReadBuffer(Pointer(Bytes)^, Ms.Size);
Result := True;
function FileToBytes(const AName: string; var Bytes: TBytes): Boolean;
var
  Stream: TFileStream;
begin
  if not FileExists(AName) then
  begin
    Result := False;
    Exit;
  end;
  Stream := TFileStream.Create(AName, fmOpenRead);
  try
    SetLength(Bytes, Stream.Size);
    Stream.ReadBuffer(Pointer(Bytes)^, Stream.Size);
  finally
    Stream.Free;
  end;
  Result := True;
end;
通过这种方式,您可以直接从文件读取到目标字节数组中

我不太喜欢将其作为一个返回布尔值表示成功的函数。除了不存在的文件之外,还有很多其他方式会导致代码失败。这些将导致您的设计出现异常。我更喜欢看到纯粹的基于异常的错误处理,或者纯粹的基于错误代码的错误处理。但不是你设计的混合方法


正如Andreas在评论中指出的,您还可以使用RTL库函数来执行此任务。尽管我个人倾向于避免使用整个
System.IOUtils
单元,因为存在许多设计问题。虽然其中一些已经在最近的版本中进行了分类,但我相信XE2版本可能会有一些问题。

字节
是一个动态数组。首先需要使用
SetLength
在其中分配足够的空间。另外,如果您的需求非常简单,请查看。为什么要编写
beginresult:=False;出口结束(四行)当一个简单的
退出(False)
(一行)就足够了吗?@AndreasRejbrand我个人从来不使用这种语法。我不喜欢有那么多方法返回值。我不喜欢在同一个函数中看到退出(值)
和结果:=value,所以我选择一种方法并总是使用它。如果我们有一个适当的
return
语句,函数结果通过值从被调用者传递给调用者,那就更好了。使用这个解决方案,我会得到一个错误:“Stream read error.”online“Stream.ReadBuffer(Pointer(Bytes),Stream.Size)”;“对不起,我会马上修复它。”。我忘了取消引用指针“如果我们有一个正确的返回语句会更好”
returnvalue
Exit(value)
有何不同?