JavaのUTF-16文字列は常に4バイトの代わりに、2つのバイトを使用します

Abdrazak魂:

私は簡単なテストを持っています

@Test
public void utf16SizeTest() throws Exception {
    final String test = "п";
    // 'п' = U+043F according to unicode table
    // 43F to binary = 0100 0011 1111 (length is 11)
    // ADD '0' so length should be = 16
    // 0000 0100 0011 1111
    // 00000100(2) 00111111(2)
    //    4(10)  63(10)
    final byte[] bytes = test.getBytes("UTF-16");
    for (byte aByte : bytes) {
        System.out.println(aByte);
    }
}

あなたが見ることができるように私には、まず「п」へのバイナリ変換しながら、多くの空刺さとして追加しますlength != 16

その出力がされます期待します 4 , 63

しかし、実際のものとなりました。

-2
-1
4
63

何が私が間違っているのでしょうか?

xingbin:

あなたがしようとした場合:

final String test = "ппп";

あなたは見つける-2 -1だけで先頭に表示されます。

-2
-1
4
63
4
63
4
63

-2 0xFEと-1です0xFF一緒に、彼らは形成しますBOM (Byte_order_mark)

UTF-16では、BOM(U + FEFF)は、ファイルまたはストリームのすべての16ビットコード単位のエンディアン(バイト順序)を示すために、ファイルまたは文字ストリームの最初の文字として配置することができます。試みは間違ったエンディアンでこのストリームを読み込むためになされた場合、バイトはこのようにテキストで表示されてはならない「非文字」としてUnicodeで定義された文字U + FFFEを、提供、スワップされます。

test.getBytes("UTF-16"); 以降のプロセッサはビッグエンディアンを使用したことを知ることができるようにBOMを正面に含まれているので、バイトを符号化するときにビッグエンディアンを使用してデフォルト。

あなたは明示的に使用して、エンディアンを指定することができますUTF-16LEUTF-16BEため、出力でBOMを避け、代わりに:

final byte[] bytes = test.getBytes("UTF-16BE");

UTF-16文字セットは、16ビット量を使用し、バイト順することが敏感です。これらのエンコーディングでは、ストリームのバイト順は、最初によって示されるバイト順マークのUnicode文字で表されます'\uFEFF'次のようにバイトオーダーマークが処理されます。

  • デコードする場合、UTF-16BEおよびUTF-16LE文字セットは、初期バイト順マークを解釈しますZERO-WIDTH NON-BREAKING SPACEエンコードするとき、彼らはバイト順マークを書き込みません

  • デコードすると、UTF-16文字セットには、バイトオーダーマークがない場合はビッグエンディアンへのストリームが、デフォルトのバイト順を示すために、入力ストリームの先頭にバイト順マークを解釈します。エンコードするとき、それはビッグエンディアンバイト順を使用し、ビッグエンディアンバイト順マークを書き込みます

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=224780&siteId=1