【问题标题】:Delphi How to search in binary file faster?Delphi如何更快地搜索二进制文件?
【发布时间】:2013-03-17 17:10:46
【问题描述】:

我有一个二进制文件 (2.5 MB),我想找到这个字节序列的位置:CD 09 D9 F5。然后我想在这个位置之后写一些数据,并用零覆盖旧数据(4 KB)。

这是我现在的做法,但有点慢。

ProcessFile(dataToWrite: string);
var
  fileContent: string;
  f: file of char;
  c: char;
  n, i, startIndex, endIndex: integer;
begin
  AssignFile(f, 'file.bin');
  reset(f);
  n := FileSize(f);
  while n > 0 do
  begin
    Read(f, c);
    fileContent := fileContent + c;
    dec(n);
  end;
  CloseFile(f);

  startindex := Pos(Char($CD)+Char($09)+Char($D9)+Char($F5), fileContent) + 4;
  endIndex := startIndex + 4088;

  Seek(f, startIndex);

  for i := 1 to length(dataToWrite) do
    Write(f, dataToWrite[i]);

  c := #0;
  while (i < endIndex) do
  begin
    Write(f, c); inc(i);
  end;

  CloseFile(f);
end;

【问题讨论】:

  • 哪部分代码比较慢?你做过计时吗?你怎么知道它很慢?它的速度是多少,您希望能够达到什么目标?
  • 按字符读取和写入文件的速度很慢。至少按更大的块将数据提取到缓冲区中(参见 BlockRead)。
  • @DavidHeffernan,是的,它正在搜索序列位置的部分很慢。现在 5 个文件大约需要 15 秒,我希望它最多 1-3 秒。例如,如果我评论它并将 StartIndex 设置为 9999,那么它就是即时的。我认为将所有文件内容逐字节读取为字符+将其复制到字符串不是最佳解决方案。
  • @DavidHeffernan,编译时间。我知道哪个部分很慢,我在上面写过 - 逐字节读取字符串并可能在该字符串中搜索。我希望 blockread 能解决我的问题...
  • 哦,天哪,我没有看到你这样做。这绝对是疯了!我会放弃 Pascal I/O。请改用流。

标签: delphi delphi-7 binaryfiles


【解决方案1】:

看到这个答案:Fast read/write from file in delphi

一些选项是:

要搜索文件缓冲区,请参阅 Best way to find position in the Stream where given byte sequence starts - 一个答案提到 Boyer-Moore algorithm 用于快速检测字节序列。

【讨论】:

  • 我只会读取一个块,扫描它的第一个字节,评估其余部分,并在适当的时候进行短路。处理出现在块末尾的序列的开始似乎是这里最明显的边缘条件。
【解决方案2】:

您将整个文件读入字符串的代码非常浪费。 Pascal I/O 使用缓冲,所以我不认为这是逐字节的方面。虽然一大读会更好。主要问题将是字符串连接和连接字符串所需的极端堆分配需求,一次一个字符。

我会这样做:

function LoadFileIntoString(const FileName: string): string;
var
  Stream: TFileStream;
begin
  Stream := TFileStream.Create(FileName, fmOpenRead);
  try
    SetLength(Result, Stream.Size);//one single heap allocation
    Stream.ReadBuffer(Pointer(Result)^, Length(Result));
  finally
    Stream.Free;
  end;
end;

仅此一项就应该有很大的不同。在写入文件时,类似地使用字符串会快得多。我没有试图破译你的代码的写作部分。写入新数据,然后再次将零块分批,尽可能少地单独写入。

如果您发现需要在文件中读取或写入非常小的块,那么我为您提供缓冲文件流:Buffered files (for faster disk access)

可以进一步优化代码以仅读取文件的一部分,并搜索直到找到目标。您也许可以避免以这种方式读取整个文件。但是,我怀疑这些更改会产生足够的影响。

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 2020-06-03
    • 2016-02-28
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    相关资源
    最近更新 更多