2016-01-21 11 views
12

Javaの 'char'は2バイトです。 (hereから確認することができます。)Javaはどのように3バイトのUnicode文字をchar型に適合させますか?

私は、このサンプルコードがあります。

public class FooBar { 
    public static void main(String[] args) { 
     String foo = "€"; 
     System.out.println(foo.getBytes().length); 
     final char[] chars = foo.toCharArray(); 
     System.out.println(chars[0]); 
    } 
} 

を、次のように出力されている:

3 
€ 

私の質問は、Javaが3バイトに合わせたのか、です文字をcharデータ型に変換しますか?最終的なファイル「バズを

File baz = new File("baz.txt"); 
final DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(baz)); 
dataOutputStream.writeChar(chars[0]); 
dataOutputStream.flush(); 
dataOutputStream.close(); 

:私は少しさらに、コードを編集して、次のステートメントを追加する場合もの-Dfile.encoding = UTF-8

:ところで、私は、パラメータを使用してアプリケーションを実行しています.txt "は2バイトのみで、UTF-8ファイルとして扱っても正しい文字は表示されません。

編集2: エンコーディングUTF-16 BEでファイル "baz.txt"を開くと、文字コードがテキストエディタで正しく表示されますが、これはわかります。

+3

Javaは内部的にUTF-16を使用します。 http://stackoverflow.com/questions/9699071/what-is-the-javas-internal-represention-for-string-modified-utf-8-utf-16 –

+0

文字は文字ではありません。 Javaの最大の問題の1つです。すべての仕組みについては、utf8everywhere.orgを参照してください。 –

答えて

8

String.getBytes()は、プラットフォームのデフォルトの文字エンコーディングを使用してバイトを返します。これは、内部表現と一致する必要はありません。

Javaが各文字に対して2バイトのRAMを使用すると、文字がUTF-8を使用して「シリアル化」されると、結果のバイト配列に1,2または3バイトが生成される可能性があります。

あなたのコード例では、UTF-8を使用しています。 Java文字列は、代わりにUTF-16を使用してメモリにエンコードされます。単一の16ビット文字に収まらないUnicodeコードポイントは、サロゲートペアと呼ばれる2文字ペアを使用してエンコードされます。

String.getBytes()にパラメータ値を渡さないと、基礎となるOSのデフォルト文字セットを使用してエンコードされたStringコンテンツを持つバイト配列が返されます。 UTF-8でエンコードされた配列を確保したい場合は、代わりにgetBytes( "UTF-8")を使用する必要があります。

String.charAt()を呼び出すと、文字列のメモリ内の記憶域からの元のUTF-16エンコードされた文字が返されます。

チェックこのリンク:java utf8 encoding - char, string types

7

Javaは、メモリ内の表現にUTF-16(16ビット)を使用しています。

ユーロ記号はUTF-8で3バイト必要ですが、それに適合します。

+1

charは常にUTF-16でエンコードされますか? –

+2

はい、それはUnicodeがそれより大きいので、少し問題です。一部のUnicodeコードポイントでは、現在Javaでは2つの文字が必要です。したがって、 "全カタログ"を使用すると、 'length'や' charAt'の結果は完全に満足できるものではないかもしれません。 – Thilo

+0

私が渡すパラメータ-Dfile.encoding = UTF-8は実際にはあまり変わっていません。 –

関連する問題