Delphi 我们能安全地在悉尼使用移动电话吗?

Delphi 我们能安全地在悉尼使用移动电话吗?,delphi,firemonkey,Delphi,Firemonkey,当我阅读时,他们说要避免使用AnsiString。有什么原因吗AnsiString使用的内存比UnicodeString少2倍,是JSON的完美容器。那么,我可以安全地使用传输,还是需要继续使用UnicodeString(为什么)?您可以在移动平台上使用8位字符串。但安全性取决于使用哪种8位字符串 对于Windows以外的任何东西,甚至在Windows上,使用AnsiString都是非常糟糕的主意AnsiString是一种遗留类型,虽然它在10.4版移动平台上重新启用,但这并不意味着您应该使用它

当我阅读时,他们说要避免使用
AnsiString
。有什么原因吗
AnsiString
使用的内存比
UnicodeString
少2倍,是JSON的完美容器。那么,我可以安全地使用
传输
,还是需要继续使用
UnicodeString
(为什么)?

您可以在移动平台上使用8位字符串。但安全性取决于使用哪种8位字符串

对于Windows以外的任何东西,甚至在Windows上,使用
AnsiString
都是非常糟糕的主意
AnsiString
是一种遗留类型,虽然它在10.4版移动平台上重新启用,但这并不意味着您应该使用它,更不意味着您可以安全地使用它

AnsiString
的一个问题是,它迟早会在代码中进行转换,因为RTL和FMX中使用的默认字符串类型都是UTF-16字符串类型,您可能会丢失原始数据

您可以在移动设备(和其他平台)上安全使用的字符串类型有
String
UTF8String
RawByteString

当涉及到
RawByteString
时,它只能安全地用于代码页不可知操作。请参阅更多:

JSON文件不支持ANSI编码,所以Unicode是您唯一的选择。UTF-8和
UTF8String
可以做得更好,因为这也是任何JSON数据交换的默认编码

就各种
AnsiXXX
函数而言,最好的选择是编写自己的例程来处理UTF-8字符串。您也可以使用在泛型字符串类型上工作的标准函数,但由于转换为UTF-16和UTF-16,它们的速度较慢


在移动设备(Android)上使用
AnsiString
时数据丢失的图示

Android规范只需要实现几个标准字符集。这包括ISO-8859-1

对于任何其他您依赖于特定设备的内容

例如,下面的示例使用
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规范化将在该过程中发生)


移动应用程序使用Unicode字符串,因此使用Anistring不会保存任何内容。无论如何,它们都会转换为Unicode,因此,来回强制执行不必要的转换只会浪费处理器时间。您也在浪费内存,因为在转换过程中必须分配临时字符串。迁移文档是在移动平台最早是在XE3前后添加到Delphi中的。那时,移动平台上的
AnsiString
被完全禁用(没有第三方编译器补丁)。在10.1中,
UTF8String
RawByteString
被重新启用。在10.4中,
AnsiString
被重新启用。因此,它是“安全的”现在使用
AnsiString
,但我不推荐(即使在桌面平台上)。仅供参考,JSON最好的字符串类型是原生
string
类型,或者至少是
UTF8String
,而不是
AnsiString
@KenWhite我不太明白你所说的“移动应用程序使用Unicode字符串”是什么意思。如果我通过API调用接收8位字符串(json)我只在我自己的算法中内部使用这个json,为什么它需要转换为Unicode字符串?json通常是用UTF-8编码的。使用
AnsiString
存储json是个坏主意。@RemyLebeau谢谢Remy!我不同意你使用UTF8string而不是AnsiString,这是因为所有的8位字符串函数(pos、stringreplace、大写、小写等)是用AnsiString声明的!如果您用其中一个函数交换UTF8String,它将在内部转换(8bit UTF8String=>UTF16=>8bit AnsiString)您让我说“JSON文件不支持ANSI编码,所以Unicode是您唯一的选择”:-)@DaveNottage我怀疑这可能是一个很有说服力的论点;)
W1057 Implicit string cast from 'string' to 'UTF8String'