2012-02-04 14 views
1

バイナリデータがある場合Dそして文字列Sに変換する場合はバイナリに変換するよりもDが得られます。しかし間違っています。バイナリデータを文字列に変換する

public class A { 
    public static void main(String[] args) throws IOException { 
     final byte[] bytes = new byte[]{-114, 104, -35};// In hex: 8E 68 DD 
     System.out.println(bytes.length);    //prints 3 
     System.out.println(new String(bytes, "UTF-8").getBytes("UTF-8").length); //prints 7 
    } 
} 

どうしてですか?

+0

文字列に任意のバイナリデータを強制しようとしていますか?どうして? – Jesper

+0

(何らかの理由で文字列のバイナリを隠す必要がある場合、バイトと文字の間に1対1のマッピングを提供するエンコーディングを使用する必要があります; ISO-8859-1は明らかな選択肢ですUTF-8には有効な文字ではないバイトシーケンスがあります。 – bobince

答えて

2

バイト配列と文字列との間の変換は、1対1のマッピング操作ではありません。 docsを参照すると、Stringインプリメンテーションでは、受信バイト配列をユニコードに変換するためにCharsetDecoderが使用されます。入力バイト配列の最初と最後のバイトは有効なユニコード文字にマップされてはならないため、一部の文字はreplacement stringに置き換えられます。

+0

良い点。しかし、それは奇妙に見えます。なぜ例外を投げるのではなく、魔法の代わりの文字列を使うべきなのでしょうか? –

+0

私は、マップできない文字に遭遇したときにCharsetDecoderから例外をスローすることができますが、デフォルトのString実装ではデフォルトのエラー文字のあまり揮発性のないオプションが使用されると思います。私はあなたがByte [] <->文字列変換をより細かく制御するためにCharsetDecoderを自分で使うことができると確信しています。 –

1

文字列に変換するバイトが実際に有効な文字列を形成しない可能性があります。 javaが各バイトの意味を理解できない場合は、それらを修正しようとします。つまり、バイト配列に変換すると、開始時と同じになりません。有効なバイトセットを試してみると、より成功するはずです。

+0

うん。しかし、私は少なくともこの場合の例外を得ることを除いて。 –

+0

動作は設定可能です。無視、置き換え、またはエラーが可能です。 http://docs.oracle.com/javase/1.5.0/docs/api/java/nio/charset/CharsetDecoder.htmlを参照してください。特に、CodingErrorActionクラスについては、 – DNA

+0

@DNAについて、良い点をありがとうございます。 –

0

データをUTF-8エンコーディングを使用して有効なUnicode文字にデコードすることはできません。デコードされた文字列を見てください。それは、0xFFFD,0x0068および0xFFFDの3つの文字で構成されています。最初と最後は " " - Unicode replacement charactersです。他のエンコーディングを選択する必要があると思います。私。 "CP866"は有効な文字列を生成し、同じ配列に変換し直します。

関連する問題