Delphi字符现在以2个字节而不是1个存储在类型化的二进制文件中。我怎么还能读取我的旧文件?

时间:2010-07-29 16:11:18

标签: delphi binary delphi-2010

我维护一个Delphi程序,它使用类型化的二进制文件作为其本机文件格式。从Turbo Delphi升级到Delphi 2010后,存储的记录类型中的所有字符开始以2个字节而不是1个字节存储。

存储的数据类型为chararray[1..5] of char

之前,该文件的一部分看起来像:

4C 20 20 20 4E 4E 4E 4E

现在看起来像:

4C 00 20 00 20 00 20 00 4E 00 4E 00 4E 00 4E 00

首先,为什么会在第一时间发生这种情况?

其次,我怎样才能读取我的文件,请记住现在宇宙中存在旧文件和新文件?

我会在午餐后痴迷地监听这个问题。请随意在评论中询问更多信息。

2 个答案:

答案 0 :(得分:11)

在Delphi 2009中将默认字符串类型从AnsiString更改为UnicodeString时发生这种情况。听起来就像是在向文件写入字符串。在记录中将它们重新声明为AnsiString,它应该可以正常工作。

同样适用于char。原始的char是一个AnsiChar,每个字符一个字节。现在默认的char是一个WideChar,它是一个UTF-16字符,每个字符2个字节。将您的char数组重新声明为AnsiChar的数组,然后您将恢复旧的文件样式。

至于知道这两种风格都存在,这是一团糟。除非升级Delphi版本时文件中的版本号已被更改,否则我认为你唯一能做的就是在字符数据中扫描00个字节,然后用{ {1}}或记录的AnsiChar版本,具体取决于是否找到记录。

答案 1 :(得分:0)

在您的代码中,将字符串类型声明更改为AnsiString,并将char类型声明更改为AnsiChar。它将使用与以前版本的Delphi相同的编码。 AnsiString / AnsiChar类型也适用于以前版本的Delphi。 但是没有全局编译器切换。 然后将此AnsiString / AnsiChar转换为unicode字符串。

这是两个例子,做同样的事情,一个使用AnsiChar数组,一个直接读取AnsiString内容。两者都返回一个通用的Unicode字符串:

function Read5(S: Stream): string;
var chars: array[1..5] of AnsiChar;
    tmp: AnsiString;
    i: integer;
begin
  S.Read(chars,5);
  for i := 1 to 5 do
    tmp := tmp+chars[i];
  result := string(tmp);
end;


function Read5(S: Stream): string;
var tmp: AnsiString;
begin
  SetLength(tmp,5);
  S.Read(tmp[1],5);
  result := string(tmp);
end;

您可以在所有程序中使用AnsiChars,没有任何问题。

但如果您的AnsiChars用于字符串函数(如pos或copy),则可能会遇到一些问题。

始终密切关注Delphi 2010编译器警告,并尝试通过使它们显式化来避免任何隐式的ansi-unicode转换。