Arrays 如何将Delphi中的文件读入字节数组?
我试图在Delphi XE2中将文件读入字节数组 这是我当前的代码: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
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)
有何不同?