0

我使用此函数将文件读取为字符串

function LoadFile(const FileName: TFileName): string;
begin
  with TFileStream.Create(FileName,
      fmOpenRead or fmShareDenyWrite) do begin
    try
      SetLength(Result, Size);
      Read(Pointer(Result)^, Size);
    except
      Result := '';  
      Free;
      raise;
    end;
    Free;
  end;
end;

这是文件的文本:

version  

这是 LoadFile 的返回值:

'ÿþv'#0'e'#0'r'#0's'#0'i'#0'o'#0'n'#0

我想制作一个包含“verabc”的新文件。问题是我仍然无法将“sion”替换为“abc”。我正在使用 D2007。如果我删除所有 #0 则结果变为汉字。

4

2 回答 2

8

您认为文件的文本实际上并不是文件的文本。您读入的字符串变量是准确的。您有一个编码为 little-endian UTF-16 的 Unicode 文本文件。前两个字节表示字节顺序标记,之后的每一对字节是字符串的另一个字符。

如果您正在读取 Unicode 文件,则应使用 Unicode 数据类型,例如WideString. 在设置字符串的长度时,您需要将文件大小除以 2,并且您需要丢弃前两个字节。

如果你不知道你正在阅读什么样的文件,那么你需要先读取前两个或三个字节。如果前两个字节是 $ff $fe,如上所述,那么您可能有一个 little-endian UTF-16 文件;将文件的其余部分读入 a WideString,或者UnicodeString如果您有该类型。如果它们是 $fe $ff,那么它可能是大端;将文件的其余部分读入 aWideString然后交换每对字节的顺序。如果前两个字节是 $ef $bb,则检查第三个字节。如果是 $bf,那么它们可能是 UTF-8 字节顺序标记。丢弃所有这三个并将文件的其余部分读入一个AnsiString或一个字节数组,然后使用类似的函数UTF8Decode将其转换为WideString.

将数据放入 中WideString后,调试器将显示它包含version,并且使用支持 Unicode 的版本进行StringReplace替换应该没有问题。

于 2010-07-01T07:44:43.587 回答
0

您似乎加载了一个 unicode 编码的文本文件。 0表示拉丁字符。

如果您不想处理 unicode 文本,请在保存文件时在编辑器中选择 ANSI 编码。

如果您需要 unicode 编码,请使用WideCharToString将其转换为 ANSI 字符串,或者只是删除自己的0s,尽管后者不是最佳解决方案。同时删除 2 个前导字符ÿþ.
编辑器放置这些字节以将文件标记为 unicode。

于 2010-07-01T07:42:49.817 回答