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

Delphi字符现在以2个字节而不是1个字节存储在键入的二进制文件中。我怎么还能读我的旧文件?,delphi,binary,delphi-2010,Delphi,Binary,Delphi 2010,我维护了一个Delphi程序,它使用键入的二进制文件作为其本机文件格式。从Turbo Delphi升级到Delphi 2010后,正在存储的记录类型中的所有字符开始以2字节而不是1字节存储 存储的数据类型是字符的char和字符的array[1..5] 所以之前,文件的一部分看起来像: 4C 20 20 20 4E 4E 4E 4E 现在看来: 4C 00 20 00 20 00 20 00 4E 00 4E 00 4E 00 4E 00 首先,为什么会发生这种情况 第二,我怎么还能读我的文件

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

存储的数据类型是字符的
char
和字符的
array[1..5]

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

4C 20 20 20 4E 4E 4E 4E
现在看来:

4C 00 20 00 20 00 20 00 4E 00 4E 00 4E 00 4E 00
首先,为什么会发生这种情况

第二,我怎么还能读我的文件,记住现在宇宙中到处都是旧文件和新文件


午饭后我会一直盯着这个问题。欢迎在评论中询问更多信息。

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

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


至于意识到这两种风格都存在,那真是一团糟。除非在升级Delphi版本时,文件中的版本号发生了更改,我想您唯一能做的就是扫描字符数据中的
00
字节,然后根据是否找到它,在
AnsiChar
WideChar
版本的记录中读取它。

在代码中,将字符串类型声明更改为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转换。

@Daniel:好的。编辑了我的答案。我可以把我所有的角色重新声明为ansichar吗?这些记录在整个程序中使用,并涉及许多其他字符变量。丹尼尔:这是一个很大的问题。我能在这两个角色之间切换,然后把记录中的角色切换到ansichars吗。unicode升级是一件非常重要的事情,unicode字符串现在是默认的字符串类型。最好在内部尽可能多地使用unicode字符串和unicode字符。通过强制转换,您可以很容易地在unicode和ansi之间进行转换。有关一些有用的提示,请参阅Cary Jensen的writeup。是否没有编译器开关来获取旧的字符大小?@Mason:我不确定是否同意。是的,很多VCL都可以处理文本,但是我很确定,大多数VCL都可以以不确定字符大小的方式实现,只需以适当的方式使用普通的Delphi字符串和字符类型即可。毕竟,这就是字符串和字符类型的用途。另一个问题是:将来如何避免这样的文件格式错误我强烈建议使用单元测试,例如使用开源DUnit测试框架。单元测试不能防止这种情况。文件头和版本号可以@Cosmin:为什么像CheckFileEquals(预期、实际)这样的回归测试没有帮助?