真 もわ爛漫

しゃーら、しゃーらしゃーら

Javaでbyte列をbyte列のまま持ってくれるようなencodingはないか 解

ISO-8859-1 で無理やりUnicodeに展開して(おそらく一旦はUnicodeのそこらじゅうに文字が散らばる)、戻すときはCharsetを使うのが良いようだ。散らばった文字列は8bitsのbyteに再び収まる。

public class encoding_exp {
  public static void main(String argv) throws Exception {
    Charset charset = Charset.forName("ISO-8859-1");
    BufferedReader reader =
        new BufferedReader(
            new InputStreamReader(
                new FileInputStream("sjis.txt"), charset));
    String line;
    while ( (line = reader.readLine()) != null ) {
      byte bytes = charset.encode(line).array();
      System.out.println(new String(bytes, "Shift_JIS"));
    }
  }
}

bytes の取り方が荒っぽい(本当は hasArray() を呼んで、falseが来たら new byte[byteBuffer.remaining()] とかしなきゃいけない)けど、これで「byte列をbyte列のまま持ってくれるような」感じにはなる。

ちなみに ISO-8859-1 ではなく UTF-8 とかだとエンコーディングできなくてエラーになる。また、Javaは仕様上 ISO-8859-1 を必ずサポートしている (Charset クラスのマニュアルを参照) ので、他のエンコーディングではなくこれがよろしい、ということで。

前回エントリで狐さんが指摘していたように String#getBytes() は間違いっぽい。デフォルトのエンコーディング (おそらく今なら UTF-8?) でbyte列に直ってしまうので、8ビットめが立っている文字列は2bytes以上の何かに飛んで行ってしまう可能性が高い。

#あんまり上の件と関係ないけど、ByteBufferを受け取るInputStreamが欲しくならない?なんかbyte配列に直すのうざいんだけど