“?” 当数据通过 Unicode 到 Ansi 转换为不支持正在转换的 Unicode 字符的 Ansi 字符集时,就会出现字符。
您使用的是什么版本的 C++Builder?在 CB2009 之前的版本中,您应该告诉 Indy 您传入的 AnsiString 数据的编码。TIdTextEncoding::ASCII
对于大多数基于字符串的操作,Indy 默认为 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);
TIdIOHandler::DefStringEncoding
如果您不想在每次调用时指定 UTF-8 编码,您也可以选择使用该属性:
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 逻辑可以解决 EmbarcaderoTEncoding
类中的一些错误。此外,我们将逐步取消对TEncoding
Indy 11 的直接支持并进行扩展,TIdTextEncoding
以便 Indy 拥有比 Embarcadero 提供的更多控制权。