きときと - Java - 文字コード変換

Javaでは、文字列は内部UnicodeのStringオブジェクトですが、Byte→String変換が正しく行われなかったときなど、
明示的な変換を必要とする場合があります。

Tomcat3.2.xなど、日本語に対応していないServletコンテナを利用する場合などによく使われます。
実際の変換には、

String unicodeStirng = new String(shift_jis_string.getBytes("iso-8859-1"), "Shift_JIS");

のようなコーディングがよく参考として挙げられます。
しかし、
など、不都合が多く、これを定型コードとしてあらかじめ知っていなければ非常に分かりにくいコードです。

「日本語処理の基本」と言ってしまえばそれまでですが、
本質的でない記述が増えるのは望ましいことではありませんし、何よりスマートでありません。(野暮ったい感じがしますね)


こういう時は文字コード変換のためのクラスを定義すると便利です。

実際の定義は後回しにして、使い方は次のようになります。

Encoding sjis = Encoding.getEncoding("Shift_JIS");
String unicodeStirng = sjis.getString(shift_jis_string);

こちらであれば、「文字コード変換を行っている」事が明確になるため、後で見てもわかりやすく、メンテナンス性のよいコーディングと言えます。

並べてみると違いが一目瞭然です。

String u1 = new String(s1.getBytes("iso-8859-1"), "Shift_JIS");
String u2 = new String(s2.getBytes("iso-8859-1"), "Shift_JIS");
String u3 = new String(s3.getBytes("iso-8859-1"), "Shift_JIS");
String u4 = new String(s4.getBytes("iso-8859-1"), "Shift_JIS");
String u5 = new String(s5.getBytes("iso-8859-1"), "Shift_JIS");

Encoding e = Encoding.getEncoding("Shift_JIS");
String u1 = e.getString(s1);
String u2 = e.getString(s2);
String u3 = e.getString(s3);
String u4 = e.getString(s4);
String u5 = e.getString(s5);



Encodingクラスのソースは以下のようになります。やっているのは、よく知られているコード変換と同じです。

Encoding.java

Encoding.java
package jp.gr.java_conf.mrig.io;
import java.io.UnsupportedEncodingException;

/**
* 文字エンコーディングを表すクラス.
* <p>
* 例1:<br>
* エンコード名を指定してEncodingオブジェクトを生成する。<br>
* <pre>
* Encoding sjis = Encoding.getEncoding("Shift_JIS");
* String unicodeString = sjis.getString(shift_jis_string);
* </pre>
* </p>
* <p>
* 例2:<br>
* 定義済みEncodingオブジェクトを利用する。<br>
* <pre>
* String unicodeString = Encoding.sjis.getString(shift_jis_string);
* </pre>
*
* 上記コードは次と等価になる.<br>
* <pre>
* String unicodeString;
* try {
* unicodeString = new String(shift_jis_string.getByte("iso-8859-1"), "Shift_JIS");
* } catch (UnsupportedEncodingException e) {
* throw new IllegalArgumentException(e.getMessage());
* }
* </pre>
* </p>
*
*/
public class Encoding {
// /** Shift_JISを表す定義済みオブジェクト */
// public static final Encoding sjis = getEncoding("Shift_JIS");
// /** EUC_JPを表す定義済みオブジェクト */
// public static final Encoding eucjp = getEncoding("EUC_JP");

/** 文字エンコーディングの文字表現 */
private final String encoding;

/**
* Encodingオブジェクトを取得する。
* @exception IllegalArgumentException <code>enc</code>がサポートされない文字コードの時
*/
public static Encoding getEncoding(String enc) {
try {
//encがサポートされない場合はUnsupportedEncodingExceptionが発生する。
new String(new byte[0], enc);
return new Encoding(enc);
} catch(UnsupportedEncodingException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

/**
* privateコンストラクタ
*/
private Encoding(String enc) {
this.encoding = enc;
}

/**
* Unicode文字列を取得する。
*/
public String getString(String s) {
if (s == null) return null;
try {
return new String(getRawBytes(s), this.encoding);
} catch(UnsupportedEncodingException e) {
//絶対に起こらないはずの例外
e.printStackTrace();
throw new IllegalStateException(e.getMessage());
}
}

/**
* <code>s</code>をiso-8859-1 文字列とみなして、byte配列に変換する。
* <p>
* 誤ってASCIIとして文字列して構築されたStringを元のバイト列に戻す時に利用する。
* </p>
* @param s 変換する文字列
*/
public static byte[] getRawBytes(String s) {
if (s == null) {
return null;
}
try {
return s.getBytes("iso-8859-1");
} catch (UnsupportedEncodingException e) {
//絶対に起こらないはずの例外
e.printStackTrace();
throw new IllegalStateException(e.getMessage());
}
}
}



ご意見・ご感想は メール kito@kun.ne.jp か掲示板 http://6005.teacup.com/kitobbs/bbs で。


LastUpdate: 2002/03/22