Delphi/windows和Linux/Lazarus共享上述字符#127

Delphi/windows和Linux/Lazarus共享上述字符#127,linux,windows,delphi,character-encoding,lazarus,Linux,Windows,Delphi,Character Encoding,Lazarus,我正在维护一个项目,其中数据必须在windows和linux机器之间共享。 该程序是在2003年在DELPHI(Windows)中开发的,因此将来两个系统都必须(至少可能)读取大量遗留数据文件 我已经将程序移植到Lazarus,它在Linux上运行得很好 但是数据(以专有格式)将字符串存储为#0-#255的通用ascii字符。在linux机器上读取数据会导致大量的“?”符号,而不是“ñ,äöüß…”等 我试图解决的问题是: 1.)我像往常一样在windows机器上读取数据。 2.)我使用修改过的

我正在维护一个项目,其中数据必须在windows和linux机器之间共享。 该程序是在2003年在DELPHI(Windows)中开发的,因此将来两个系统都必须(至少可能)读取大量遗留数据文件

我已经将程序移植到Lazarus,它在Linux上运行得很好

但是数据(以专有格式)将字符串存储为#0-#255的通用ascii字符。在linux机器上读取数据会导致大量的“?”符号,而不是“ñ,äöüß…”等

我试图解决的问题是:

1.)我像往常一样在windows机器上读取数据。 2.)我使用修改过的版本保存了数据,该版本将使用URLEncode()对所有字符串进行编码 关于储蓄。 3.)我还修改了使用URLDecode读取数据的例程 4.)我用修改过的版本保存了数据。 5.)我在linux上编译了修改后的版本,并从windows机器上复制了数据。 6.)我打开了有问题的数据。。。并得到问号(?)而不是“ñ,äöüß…”等

那么,实际的问题是:如何共享由两个系统维护的数据,并在编辑数据时保留这些字符(在两侧)?
提前感谢

8位Ansi128-255之间的值是特定于字符集的。无论使用什么字符集在Windows上保存数据(假设您依赖于Windows默认编码,这取决于用户的区域设置),在Linux上加载数据时都必须使用相同的字符集,反之亦然。世界上使用的字符集有几十个,甚至数百个,这使得Ansi数据的可移植性很困难。这正是Unicode设计用来解决的问题。最好将数据保存在便携式字符集(如UTF-8)中,然后在加载/保存数据时执行与系统字符集之间的转换。

考虑使用UTF-8进行转换

或者,如果您确定数据始终具有相同的代码页,则可以使用从原始Windows代码页到UTF-8的转换,这是默认的Linux/Lazarus编码


如果希望应用程序文件格式跨平台,最好不要依赖任何专有的二进制布局。您刚刚发现了字符编码问题,但可能还有其他问题,如二进制尾数。SQLite3是一个非常好的工具。它快速、可靠、跨平台、稳定且原子化。

请注意,Lazarus总是要求GUI使用utf8字符串。因此,即使在Windows上,如果没有适当的utf8卫生设备,这也可能无法工作

有机会使用UTF-8进行改装吗?重要提示:ASCII范围以#127结尾。ASCII是一个7位字符集。序号在0到127之间。因此,127以上的值不是ASCII。你需要了解它们是什么。可能是Windows ANSI。在Linux下加载时,您可能将其解释为UTF-8。明智的做法是从ANSI转换到UTF-8。第一步是学习什么是Unicode。必须准确地知道被视为问号的字节的含义。此答案显示了如何诊断正在发生的情况问题是/将要发生的问题:仍有Windows用户在使用该程序。最新的Windows可执行文件是使用不支持Unicode的BDS2006创建的。Delphi的最新版本不可用。因此,转换所有数据文件很容易编写,但这不是一个解决方案。@hy soft请注意,您混淆了Unicode和UTF-16。如果您在BDS2006字符串或文件中使用UTF-8编码(如Remy所建议的),您的业务代码将完全支持Unicode。VCL本身与系统代码页绑定,这是因为Windows限制从未在系统级别实现UTF-8,而Linux确实选择UTF-8以实现其API的完全Unicode支持,使用常规的8位字符宽度。一些代码重构以使用UTF-8编码进行存储是解决方案——也许使用一种可移植的文件格式,如SQlite3——请参阅,谢谢@ArnaudBouchez,我会尝试一下——但我要到今晚(格林尼治标准时间)才能尝试。@hy-soft:仅仅因为您使用的是Delphi的前Unicode版本,并不意味着您不能使用Unicode数据。您可以使用
WideString
将UTF-16编码文本保存在内存中,并且在保存/加载数据时可以使用RTL的
UTF8Encode()
UTF8Decode()
函数。如果您需要在UI中使用Unicode,您可以使用第三方控件,如TNTWare。谢谢@RemyLebeau,这是一个很好的提示。今天我希望有时间来测试它,并给出一些反馈。