質問: stext.getBytes("ISO8859_1"); // Shift-JISのコードを表示 for (byte b: bytes) { System.out.print(String.format("%02X ", (int)b & 0xff)); } } } ```
回答: UTF-8のファイルをSJISに変換後で文字化け。の関連質問のようなので、こちらにも補足を書かせていただきます。 まずはあなたのコード中で`original.getBytes("Shift-JIS")`というのは、元の文字列をShift_JISエンコーディングのバイト列に変換します。結果はあなたも書いておられますが、 > > > ``` > 92 B7 8F 8A 82 C6 92 5A 8F 8A > > ``` > > ですね。上記のコードを取り囲んでいる、`new String(..., "ISO8859_1")`と言うのは、そのバイト列をISO-8859-1(通称ISO-LATIN1)エンコーディングの文字列としてJavaの内部表現に変換します。 ISO-8859-1 上記のバイト列をISO-8859-1の文字コード表にしたがって変換していくと、 > > > ``` > 92: <未定義の制御コード> > B7: · (欧文中点) > 8F: <未定義の制御コード> > 8A: <未定義の制御コード> > 82: <未定義の制御コード> > C6: Æ (AとEのリガチャー) > 5A: Z (普通のアルファベット大文字Z) > 8F: <未定義の制御コード> > 8A: <未定義の制御コード> > > ``` > > となります。 <未定義の制御コード>の部分はどんな表示になるか環境依存ということになりますが、それ以外の部分は上記の文字が表示されていないでしょうか。 次の`byte[]bytes = stext.getBytes("ISO8859_1");`では`stext`の中身の文字列をISO-8859-1エンコーディングのバイト列に変換しています。これは先の`new String(..., "ISO8859_1")`の逆操作ですから、その前のバイト列、つまり`original.getBytes("Shift-JIS")`と同じ結果を返すのは当然、と言うことになります。 文字列の内部表現としてバイト列をそのまま格納するPHP(細かい違いはあるがPythonやRubyも同様)なんかでは、ISO-8859-1としてそのバイト列を解釈させることにより、1文字=1バイトになるので、中身の各バイトを取り出しやすくするためにISO-8859-1に変換するというのはよく知られたテクニックなのですが、それはJavaには通用しません。 上記のような言語では、文字列処理として文字コード変換をした後、その文字列をそのままファイルに書き出せば文字コード変換が行われますが、Javaでは一旦Java文字列として正しく読み込まれたものに何らかのコード変換を行うようなことはせず、ファイルへの出力の際に出力文字コードを指定することで、文字コード変換を行わせます。(`System.out`は勝手にプラットフォームのデフォルト文字コードに変換してしまうので、そういう意味では文字コード変換結果の出力には使うべきではないでしょう。) Java(その他C#やJavaScriptやObjective-CやSwiftや...)とPHP系の文字列の取り扱いはそういう部分では大きく異なります。Javaでコーディングするのであれば、Java流に慣れてください。