'?'当数据通过 Unicode 到 Ansi 转换为不支持正在转换的 Unicode 字符的 Ansi 字符集时,就会出现字符。
您使用的是哪个版本的 C++Builder?在 CB2009 之前的版本中,您应该告诉 Indy 您传入的 AnsiString 数据的编码。对于大多数基于字符串的操作,Indy 默认为 ASCII(即:TIdTextEncoding::ASCII)。可以在需要时使用可选的AAnsiEncoding 参数、TIdIOHandler::DefAnsiEncoding 属性或全局Idglobal::GIdDefaultAnsiEncoding 设置来覆盖它。如果未指定正确的编码,则 AnsiString 数据在转换为 UTF-8 之前可能无法正确转换为 Unicode。例如:
AContext->Connection->IOHandler->WriteLn(cxMemo1->Text, TIdTextEncoding_UTF8, TTIdTextEncoding_Default);
或者:
AContext->Connection->IOHandler->DefAnsiEncoding = TIdTextEncoding_Default;
AContext->Connection->IOHandler->WriteLn(cxMemo1->Text, TIdTextEncoding_UTF8);
如果您不想在每次调用时指定 UTF-8 编码,您也可以选择使用 TIdIOHandler::DefStringEncoding 属性:
AContext->Connection->IOHandler->DefStringEncoding = TIdTextEncoding_UTF8;
AContext->Connection->IOHandler->WriteLn(cxMemo1->Text);
现在,话虽如此,WriteFile() 也在发送 J2ME 未正确处理的数据这一事实告诉我,Indy 不是问题的根源。 WriteFile() 只是将原始文件数据原样复制到连接中,根本没有任何解释。如果您发送一个 UTF-8 编码的文件,那么 UTF-8 编码的八位字节将被发送到 J2ME。
我建议您使用数据包嗅探器(例如 Wireshark)来验证 Indy 发送的数据。这将确定 Indy 是否真的有过错。
*PS:请注意,在上面的示例中,我直接使用 Indy 的 TIdTextEncoding 宏而不是 TEncoding。这是因为 Indy 的 TIdTextEncoding 逻辑可以解决 Embarcadero 的 TEncoding 类中的一些错误。此外,我们将在 Indy 11 中逐步停止对 TEncoding 的直接支持,并扩展 TIdTextEncoding,因此 Indy 拥有比 Embarcadero 提供的更多控制权。