当前位置:  开发笔记 > 开发工具 > 正文

在delphi中从文件快速读/写

如何解决《在delphi中从文件快速读/写》经验,为你挑选了3个好方法。

我正在以二进制形式将文件加载到一个数组中,这似乎需要一段时间才有更好更快更有效的方法来执行此操作.我正在使用类似的方法写回文件.

procedure openfile(fname:string);
var
    myfile: file;
    filesizevalue,i:integer;
begin
  assignfile(myfile,fname);
  filesizevalue:=GetFileSize(fname); //my method
  SetLength(dataarray, filesizevalue);
  i:=0;
  Reset(myFile, 1);
  while not Eof(myFile) do
    begin
      BlockRead(myfile,dataarray[i], 1);
      i:=i+1;
    end;
  CloseFile(myfile);
end;

Davy Landman.. 16

如果你真的想快速读取二进制文件,让windows担心缓冲;-)使用内存映射文件.使用它,您可以简单地将文件映射到内存位置,读取就像它是一个数组.

你的功能将成为:

procedure openfile(fname:string);
var
    InputFile: TMappedFile;
begin
  InputFile := TMappedFile.Create;
  try
    InputFile.MapFile(fname);
    SetLength(dataarray, InputFile.Size);
    Move(PByteArray(InputFile.Content)[0], Result[0], InputFile.Size);
  finally
    InputFile.Free;
  end;
end;

但我建议不要使用全局变量dataarray,但要么将其作为参数传递给var,要么使用返回结果数组的函数.

procedure ReadBytesFromFile(const AFileName : String; var ADestination : TByteArray);
var
    InputFile : TMappedFile;
begin
  InputFile := TMappedFile.Create;
  try
    InputFile.MapFile(AFileName);
    SetLength(ADestination, InputFile.Size);
    Move(PByteArray(InputFile.Content)[0], ADestination[0], InputFile.Size);
  finally
    InputFile.Free;
  end;
end;

TMappedFile来自我的文章使用内存映射快速读取文件,本文还包含如何将其用于更多"高级"二进制文件的示例.



1> Davy Landman..:

如果你真的想快速读取二进制文件,让windows担心缓冲;-)使用内存映射文件.使用它,您可以简单地将文件映射到内存位置,读取就像它是一个数组.

你的功能将成为:

procedure openfile(fname:string);
var
    InputFile: TMappedFile;
begin
  InputFile := TMappedFile.Create;
  try
    InputFile.MapFile(fname);
    SetLength(dataarray, InputFile.Size);
    Move(PByteArray(InputFile.Content)[0], Result[0], InputFile.Size);
  finally
    InputFile.Free;
  end;
end;

但我建议不要使用全局变量dataarray,但要么将其作为参数传递给var,要么使用返回结果数组的函数.

procedure ReadBytesFromFile(const AFileName : String; var ADestination : TByteArray);
var
    InputFile : TMappedFile;
begin
  InputFile := TMappedFile.Create;
  try
    InputFile.MapFile(AFileName);
    SetLength(ADestination, InputFile.Size);
    Move(PByteArray(InputFile.Content)[0], ADestination[0], InputFile.Size);
  finally
    InputFile.Free;
  end;
end;

TMappedFile来自我的文章使用内存映射快速读取文件,本文还包含如何将其用于更多"高级"二进制文件的示例.



2> schnaader..:

您通常不应该逐字节读取文件.使用具有较大值的BlockRead(通常最好使用512或1024)并使用其返回值来查找读取的字节数.

如果大小不是太大(并且你使用SetLength似乎支持这个),你也可以使用一个BlockRead调用一次读取整个文件.因此,修改您的方法,这将是:

AssignFile(myfile,fname);
filesizevalue := GetFileSize(fname);
Reset(myFile, 1);
SetLength(dataarray, filesizevalue);
BlockRead(myFile, dataarray[0], filesizevalue);
CloseFile(myfile);

也许你也可以改变程序名为OpenAndReadFile一个布尔函数返回false,如果该文件无法打开或读取.



3> Toon Krijthe..:

这取决于文件格式.如果它由几个相同的记录组成,您可以决定创建该记录类型的文件.

例如:

type
  TMyRecord = record
    fieldA: integer;

    ..
  end;
  TMyFile = file of TMyRecord;

  const
    cBufLen = 100 * sizeof(TMyRecord);
  var
    file: TMyFile;
    i : Integer;

  begin
    AssignFile(file, filename);
    Reset(file);
    i := 0;
    try
      while not Eof(file) do begin
        BlockRead(file, dataarray[i], cBufLen);
        Inc(i, cBufLen);
      end;
    finally
      CloseFile(file);
    end;
  end;

推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有