我正在以二进制形式将文件加载到一个数组中,这似乎需要一段时间才有更好更快更有效的方法来执行此操作.我正在使用类似的方法写回文件.
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来自我的文章使用内存映射快速读取文件,本文还包含如何将其用于更多"高级"二进制文件的示例.
如果你真的想快速读取二进制文件,让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来自我的文章使用内存映射快速读取文件,本文还包含如何将其用于更多"高级"二进制文件的示例.
您通常不应该逐字节读取文件.使用具有较大值的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,如果该文件无法打开或读取.
这取决于文件格式.如果它由几个相同的记录组成,您可以决定创建该记录类型的文件.
例如:
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;