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

发布于 2024-09-11 15:11:19 字数 454 浏览 1 评论 0原文

我维护一个 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

首先,为什么会发生这种情况?

其次,我怎样才能仍然读取我的文件,同时记住现在宇宙中漂浮着旧文件和新文件?

午饭后我会密切关注这个问题。请随时在评论中询问更多信息。

I maintain a Delphi program which uses typed binary files as its native file format. After upgrading from Turbo Delphi to Delphi 2010, all chars in the record type being stored started being stored with 2 bytes rather than one.

The data types being stored are char and array[1..5] of char.

So before, part of the file looked like:

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

Now it looks like:

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

First of all, why did this happen in the first place?

Secondly, how can I still read my files, keeping in mind that there are now old files and new files floating around in the universe?

I will monitor this question obsessively after lunch. Feel free to ask for more information in comments.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

居里长安 2024-09-18 15:11:19

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

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

至于意识到两种风格都存在,那是一团糟。除非文件中的版本号之类的东西在您升级 Delphi 版本时已更改,否则我想您唯一能做的就是扫描字符数据中的 00 字节,然后将其读入记录的 AnsiCharWideChar 版本取决于是否找到记录。

This happened when the default string type was changed from AnsiString to UnicodeString in Delphi 2009. Sounds like you were writing strings to the file. Redeclare them in the record as AnsiString and it should work fine.

Same goes for char. The original char was an AnsiChar, one byte per character. Now the default char is a WideChar, which is a UTF-16 char, 2 bytes per character. Redeclare your char arrays as arrays of AnsiChar and you'll get your old file style back.

As for being aware that both styles exist, that's a mess. Unless there's something like a version number in the file that's been changed when you upgraded your Delphi version, I suppose the only thing you can do is scan for 00 bytes in the character data and then have it read in either a AnsiChar or a WideChar version of the record based on whether it finds it.

晌融 2024-09-18 15:11:19

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

In your code, change the string type declaration to AnsiString, and char type declaration to AnsiChar. It will use the same encoding than with previous version of Delphi.
And AnsiString/AnsiChar types work also with previous versions of Delphi.
But there is no global compiler switch.
Then convert this AnsiString/AnsiChar to unicode string.

Here are two examples, doing the same thing, one using an array of AnsiChar, one with direct reading of an AnsiString content. Both return a generic Unicode string:

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;

You can use AnsiChars in all your program, without any problem.

But you may have some problems if your AnsiChars are used in string functions (like pos or copy).

Always take a close look to Delphi 2010 compiler warnings, and try to avoid any implicit ansi-unicode conversion by making them explicit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文