タイトル | : Re: FTP Socket,LISTで全角文字が正常に表示されない |
記事No | : 11354 |
投稿日 | : 2014/12/11(Thu) 14:05 |
投稿者 | : Hongliang |
まず前提として、FTPでは文字集合/文字符号化方式について、ほとんどのサーバ/クライアントが従っている デファクトスタンダードというものが存在していません。 ですので、クライアントはサーバ毎に有効な文字エンコーディングを選択する必要があります。
さて、元のソースを見ると、バイト配列から文字列に変換する際に、Encoding.ASCIIを使用していますね。 ASCIIは0x00〜0x7Fまでの英数字と一部記号程度しか扱わないエンコーディングですので、当然全角文字は 変な変換になってしまいます。 任意のエンコーディングを使ってバイト配列から文字列に変換するには、 Encoding.GetEncoding静的メソッドによってEncodingオブジェクトを取得し、 それを使って変換処理を行うことになります。 たとえばShift_JISを使っているサーバなら、Encoding.GetEncoding("Shift_JIS")みたいな。
> 受信時に1バイトづつ読んで文字コード変換とかしているように見えますが いえ、Receiveで取得したバイト配列毎に文字列に変換していますよ。 ただマルチバイト文字列の場合、このままだと1文字を表す2バイトの真ん中までで一旦Receiveが完了した場合に、 その部分の文字が化けることになります。 たとえば「いいえ」の3文字はShift_JISだと82 A2 82 A2 82 A6という6バイトになりますが、 82 A2 82とA2 82 A6 という2回に分割されてそれぞれReceiveする可能性があります。 これらにそれぞれEncoding::GetStringすると、"い・"、"「え"という文字列になってしまいます。 これを防ぐためには、EncodingオブジェクトのGetDecoderメソッドで取得できるDecoderオブジェクトを使って 変換処理を行うのがベターです。
Dim text As New StringBuilder() Dim buffer(m_aBuffer.Length - 1) As Char Dim dec As Decoder = m_encoding.GetDecoder() ' m_encodingは元ソースではASCIIという名前のメンバ変数 Do While (True) bytes = cSocket.Receive(m_aBuffer, m_aBuffer.Length, 0) Dim converted As Integer = dec.GetChars(m_aBuffer, 0, bytes, buffer, 0) text.Append(buffer, 0 converted) If (bytes < m_aBuffer.Length) Then Exit Do End If Loop
mess = text.ToString().Split(seperator)
|