「?」文字は、データがUnicodeからAnsiへの変換を経て、変換されるUnicode文字をサポートしないAnsi文字セットに変換されるときに発生します。
どのバージョンのC++Builderを使用していますか?CB2009より前のバージョンでは、渡すAnsiStringデータのエンコーディングをIndyに通知する必要があります。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に送信されます。
Indyが送信しているデータを確認するには、Wiresharkなどのパケットスニファを使用することをお勧めします。それは、インディが本当に過ちを犯しているかどうかを確実に教えてくれます。
* PS:上記の例では、直接TIdTextEncoding
ではなくIndyのマクロを使用していることに注意してください。TEncoding
これは、IndyのTIdTextEncodingロジックが、EmbarcaderoのTEncoding
クラスのいくつかのバグを回避するためです。また、Indy 11での直接サポートを段階的に廃止しTEncoding
、拡張してTIdTextEncoding
、IndyがEmbarcaderoが提供するよりも多くの制御を行えるようにします。