web-dev-qa-db-ja.com

Java InputStreamエンコーディング/文字セット

次の(例)コードを実行する

_import Java.io.*;

public class test {
    public static void main(String[] args) throws Exception {
        byte[] buf = {-27};
        InputStream is = new ByteArrayInputStream(buf);
        BufferedReader r = new BufferedReader(
                new InputStreamReader(is, "ISO-8859-1"));
        String s = r.readLine();
        System.out.println("test.Java:9 [byte] (char)" + (char)s.getBytes()[0] + 
                " (int)" + (int)s.getBytes()[0]);
        System.out.println("test.Java:10 [char] (char)" + (char)s.charAt(0) + 
                " (int)" + (int)s.charAt(0));
        System.out.println("test.Java:11 string below");
        System.out.println(s);
        System.out.println("test.Java:13 string above");
    }
}
_

この出力をくれ

 test.Java:9 [byte](char)? (int)63 
 test.Java:10 [char](char)? (int)229 
 test.Java:11文字列以下
?
 test.Java:13文字列上

9行目の出力で正しいバイト値(-27)を保持するにはどうすればよいですか?その結果、System.out.println(s)コマンド(å)の予期される出力を受け取ります。

14
Tobbe

byte値を保持する場合は、理想的にはリーダーを使用しないでください。任意のバイナリデータをテキストで表し、後でバイナリデータに変換するには、base16またはbase64エンコーディングを使用する必要があります。

ただし、何が起こっているのかを説明するために、s.getBytes()を呼び出すと、default文字エンコーディングが使用されます。これには、明らかにUnicode文字U + 00E5が含まれていません。

s.getBytes("ISO-8859-1")の代わりにどこでもs.getBytes()を呼び出すと、正しいバイト値が返されると思います...しかし、これをISO-8859-1に依存することは、ちょっと汚いIMOです。

21
Jon Skeet

前述のように、getBytes()(引数なし)はJavaプラットフォームのデフォルトのエンコーディングを使用しますが、ISO-8859-1ではない可能性があります。端末を提供すれば、印刷するだけで動作しますとデフォルトのエンコーディングは一致し、文字をサポートします。たとえば、私のシステムでは、ターミナルとデフォルトのJavaエンコーディングは両方ともUTF-8です。「?」が表示されているという事実は、あなたのものが一致しないか、åはサポートされていません。

システムで手動でUTF-8にエンコードする場合は、次のようにします。

String s = r.readLine();
byte[] utf8Bytes = s.getBytes("UTF-8");

{-61, -91}でバイト配列を提供する必要があります。

7