我们可以在悉尼的移动设备中安全地使用ansiString吗?
当我阅读从桌面迁移 Delphi 代码到移动设备时,他们说要避免使用AnsiString. 有什么理由吗?AnsiString使用的内存比 少 2 倍UnicodeString,它是 JSON 的完美容器。那么,我可以AnsiString安全使用,还是需要继续使用UnicodeString(以及为什么)?
回答
您可以在移动平台上使用 8 位字符串。但是安全性取决于您使用哪种 8 位字符串。
对于 Windows 以外的任何东西,甚至在 Windows 上,使用AnsiString都是非常糟糕的主意。AnsiString是遗留类型,虽然它在 10.4 移动平台上重新启用,但这并不意味着你应该使用它,更不用说你可以安全地使用它。
问题之一AnsiString是在您的代码中迟早会进行转换,因为在 RTL 和 FMX 中使用的默认字符串类型是 UTF-16 字符串类型,您可能会丢失原始数据。
您可以在移动设备(和其他平台)上安全使用的字符串类型是string,UTF8String和RawByteString。
说到它,RawByteString它只能安全地用于代码页不可知的操作。查看更多:Delphi XE - RawByteString 与 AnsiString
JSON 文件不支持 ANSI 编码,因此 Unicode 是您唯一的选择。UTF-8UTF8String会做得很好,因为这也是任何 JSON 数据交换的默认编码。
就各种AnsiXXX函数而言,最好的选择是编写自己的例程来处理 UTF-8 字符串。您还可以使用适用于通用字符串类型的标准函数,但由于转换为 UTF-16 并返回,因此速度较慢。
AnsiString在移动设备上使用时数据丢失的图示(Android)
Android 规范只需要实现几个标准字符集。这包括 ISO-8859-1
https://developer.android.com/reference/java/nio/charset/Charset
对于其他任何事情,您都取决于特定设备。
例如,下面的示例AnsiString对于法语字符集工作正常,但对于克罗地亚语和中文则失败。
var
s: string;
u: UTF8String;
a: AnsiString;
begin
s := 'é à è ù â ê î ô û ç ë ï ü';
a := s;
u := s;
Memo1.Lines.Add(s);
Memo1.Lines.Add(u);
Memo1.Lines.Add(a);
s := 'š ? ? ? ž Š ? ? ? Ž';
a := s;
u := s;
Memo1.Lines.Add(s);
Memo1.Lines.Add(u);
Memo1.Lines.Add(a);
s := '??';
u := s;
a := s;
Memo1.Lines.Add(s);
Memo1.Lines.Add(u);
Memo1.Lines.Add(a);
end;
当您在可能发生数据丢失的位置之间进行不安全的类型转换时,Delphi 编译器将发出警告,并且通过使用其他一些字符串类型来修复所有代码是明智的。
W1058 Implicit string cast with potential data loss from 'string' to 'AnsiString'
当您直接在 UTF-8 和 UTF-16 字符串类型之间转换时也会出现警告,但要清除这些警告,您只需明确地将类型转换为string或UTF8String类型,因为编译器将在后台进行适当的转换并且所有信息都将被保留(注意:在该过程中可能会发生 Unicode 规范化)。
W1057 Implicit string cast from 'string' to 'UTF8String'