如何让PChar通过Hex 00s到达Delphi中的文件末尾?

lke*_*ler 2 delphi parsing large-files pchar

我正在解析非常大的文件(Unicode - Delphi 2009),并且我有一个非常有效的例程,使用PChar变量,如Stackoverflow问题中所述:在Delphi中解析一行的最快方法是什么?

一切都运行良好,直到我遇到一个文件中有一些嵌入的十六进制:00字符.此字符表示PChar字符串的结尾,我的解析在此时停止.

但是,当您加载文件时,如:

FileStream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite);
Size := FileStream.Size;
Run Code Online (Sandbox Code Playgroud)

然后你会发现文件的大小要大得多.如果用记事本打开文件,它会加载到文件的末尾,而不是像PChar那样停在第一个十六进制:00.

如何在仍然使用PChar解析的同时读取到文件的末尾而不会减慢我的读取/解析太多?

Zoë*_*son 5

当你的另一个问题达到#0字符时,你接受的代码就会爆发.要修复它,您只需要保存输入的长度并检查它.更新后的代码如下所示:

type
  TLexer = class
  private
    FData: string;
    FTokenStart: PChar;
    FCurrPos: PChar;
    FEndPos: PChar;                                         // << New
    function GetCurrentToken: string;
  public
    constructor Create(const AData: string);
    function GetNextToken: Boolean;
    property CurrentToken: string read GetCurrentToken;
  end;

{ TLexer }

constructor TLexer.Create(const AData: string);
begin
  FData := AData;
  FCurrPos := PChar(FData);
  FEndPos := FCurrPos + Length(AData);                      // << New
end;

function TLexer.GetCurrentToken: string;
begin
  SetString(Result, FTokenStart, FCurrPos - FTokenStart);
end;

function TLexer.GetNextToken: Boolean;
var
  cp: PChar;
begin
  cp := FCurrPos; // copy to local to permit register allocation

  // skip whitespace
  while (cp <> FEndPos) and (cp^ <= #32) do                 // << Changed
    Inc(cp);

  // terminate at end of input
  Result := cp <> FEndPos;                                  // << Changed

  if Result then
  begin
    FTokenStart := cp;
    Inc(cp);
    while (cp <> FEndPos) and (cp^ > #32) do                // << Changed
      Inc(cp);
  end;

  FCurrPos := cp;
end;
Run Code Online (Sandbox Code Playgroud)