next up previous contents
Next: Stringとchar[]byte[] Up: JDK1.1での日本語処理 Previous: Java String

Converterクラス

charとbyteのこの区別が、「内部と外部」に加えて、「Unicodeとその他のコード」 という二重の意味を負わされていることに注意して下さい。

JDK1.1で、charとbyteの相互の変換の為に、新たに導入された二つのクラス、 ByteToCharConverterとCharToByteConverterの働きを理解する鍵は、まさにその点に あるのです。JDK1.1の早いバージョンでは、これらのコンバータクラスは、 java.ioパッケージに属していたのですが、後で、sun.ioパッケージに移されて、 目に付きにくくなりましたが、この二つのコンバータ・クラスの働きを理解することが JDK1.1での日本語対応を理解する上で、決定的に重要です。

ByteToCharConverterは、Java の外部の様々のコード体系で表現されたデータを、 Java での文字列処理が可能な内部コード、すなわち、Unicodeに変換します。 CharToByteConverterは、逆に、Java の内部コードであるUnicodeを、Java の外部の 様々のコードのbyte列に変換します。

実は、Converterクラスはabstractクラスで、そのままでは、コンストラクタで インスタンスを作る事が出来ません。それで、次に見る例のように、内部のstatic メソッドgetConverter()を呼び出すことで、インスタンスを獲得します。 sun.io 以下のパッケージに、ByteToChar<コード名>、あるいは、 sun.io.CharToByte<コード名>といった名前をもつクラスが、沢山用意されています。 getConverter()は、これからインスタンスを生成します。 JDK1.1のInternationalization (長いので、Xにならって、'i18n'と略すことに しましょう)のドキュメントには、次のようなサンプルがのっています。

    String str = "The quick br own fox";
    byte[] output;
    CharToByteConverter fromUnicode
        = CharToByteConverter.getConverter("SJIS");
    output = fromUnicode.convertAll( str.toCharArray() );

このサンプルが、完全なものではなく、fragmentであることは分かりますが、 少しショックだったのは、このサンプルが、まったく無意味な「変換」を行っている ことです。"The quick brown fox" は、SJISに変換しても、"The quick brown fox" に変わりはありません。JDK1.1のi18nのドキュメントの作者は、日本の"SJIS"という コードが、何かとんでもないコードであるように考えているようです。 この例は、変換されるべきコードを、SJIS等の日本のJIS系のコードではなく、例えば、 アメリカ産のEBCDICコードにすれば、十分、意味があるものになります。

Default Encoding

読者の中には、Sun上で日本語を使っている人も多いはずです。この時、ファイルや 標準の入出力は、基本的には、EUCコードが使われることになります。 いま、Sunの日本語環境のもとで、あるファイルのデータを読んで、一定の処理を 行い、別のファイルに結果を書き出すJava のプログラムがあったとしましょう。 JDK1.1が想定しているのは、次のようなシナリオです。

第一。まず、データの入力時に、外部のEUCコードを内部のUnicodeに変換します。 この時、ByteToCharConverter.getConverter("EUCJIS")で獲得されたコンバータが 使われます。 第二。文字列データの処理は、全てUnicodeで行われます。ですから、処理結果 は、内部的にはUnicodeのままです。 第三。データの出力時に、Unicodeは、EUCに変換されます。この時には、 CharToByteConverter.getConverter("EUCJIS")で獲得されたコンバータが使われます。

あるコードを他のコードに変換するコードのコンバータを指定するには、一般には、 二つのパラメータが必要となります。このJavaのシナリオの場合には、変換対象の 一方は常にUnicodeですので、パラメータは一つですみます。 当然のことですが、先の、ByteToCharConverter.getConverter("EUCJIS")と、 CharToByteConverter.getConverter("EUCJIS")の引数が同じことに留意して下さい。

もしも、読者がPC上で日本語を使っているのなら、先の引数の"EUCJIS"が、"SJIS" に変わる事になります。MACユーザなら、コンバータの引数に、やはり"SJIS"を与え なけらばならないでしょう。 このように、Javaから見れば、プラットホーム、OSの違い、国毎に、使用 されるコードは異なるのですが、あるマシンのユーザからみれば、そこでは、 常に同じ特定のコードが使われるということになります。JDK1.1では、 System Property の中に、"file.encoding" というプロパティがあって、 ここに、このシステム毎のデフォールトのコード名が設定されています。 JDK1.1では、ByteToCharConverterにも CharToByteConverterにも、getDefault() というメソッドがあって、"file.encoding"プロパティに設定されたコード名を 利用して、自動的にシステムにあったコンバータをつくり出してくれます。 これは、プラットホームに依存しないプログラムを作るには、便利な手法です。



maruyama@wakhok.ac.jp