初出 JAVA PRESS Vol.29

Java API ダイジェスト

java.nio.charset.Charset
java.nio.charset.CharsetEncoder
java.nio.charset.CharsetDecoder

Charset クラスは文字集合を表すクラスです。文字集合としてIANAで定義されている正準名とエイリアスをサポートします。また、文字集合の追加も可能です。

Charsetクラスとともに用いられるのが、char列から byte列への変換を行うCharsetEncoderクラスと、 byte列からcha列 への変換を行うCharsetDecoderクラスです。この2つのクラスを使用して文字列のエンコード・デコードを行います。


文字集合を表すクラス

Charsetクラスは文字集合を表し、byte列とchar列のマッピングを示します。

Charsetオブジェクトの生成はforNameメソッドを使用します。引数は文字集合名です。

生成

Charsetオブジェクトに対応するCharsetEncoder/CharsetDecoderを生成するにはnewEncoder/newDecoderメソッドを使用します。

CharsetEncoderの生成

CharsetDecoderの生成

char列からbyte列への変換はencodeメソッド、逆にbyte列からchar列への変換はdecodeメソッドを使用します。

char列からbyte列への変換

byte列からchar列への変換

文字集合と変換

生成

public static Charset forName(String charsetName)

Charsetrオブジェクトを生成するためのファクトリメソッドです。引数は文字集合名です。文字集合名にはIANAで定義されている正準名とエイリアスがあります。例えば、シフトJISの場合、Shift_JISが正準名で、MS_KanjiやShift-JISなどがエイリアスになります。リスト1ではシフトJISのCharsetオブジェクトを正準名とエイリアスで生成しています。

リスト 1 シフトJISのCharsetオブジェクトの生成例

    Charset charset1 = Charset.forName("Shift_JIS");
    Charset charset2 = Charset.forName("MS_Kanji");
    Charset charset3 = Charset.forName("Shift-JIS");

CharsetEncoderオブジェクトの生成

public CharsetEncoder newEncoder()

CharsetオブジェクトからCharsetEncoderを生成します。

CharsetDecoderオブジェクトの生成

public CharsetDecoder newDecoder()

CharsetオブジェクトからCharsetDecoderを生成します。

char列からbyte列への変換

public ByteBuffer encode(CharBuffer cb)
public ByteBuffer encode(String str)
public ByteBuffer encode(CharBuffer in)
public CoderResult encode(CharBuffer in, ByteBuffer out, boolean endOfInput)

char列からbyte列に変換するencodeメソッドはCharsetクラスとCharsetEncoderクラスの両方に定義されていますが、Charsetクラスで定義されたものはCharsetEncodeクラスのencodeメソッドをコールしているだけの簡易メソッドになっています。

CharBufferもしくはStinrが引数のencodeメソッドは一括変換を行います。しかし、一括で変換することができない場合、endOfInputを引数とするencodeメソッドを利用します。このメソッドの使用法は次のようになります。

  1. reset() メソッドをコールして初期化する
  2. 追加の入力が無くなるまでencodeメソッドを繰り返しコールする。このときendOfInputはfalseにしておく
  3. 最後の入力の時にendOfInputをtrueにして、encodeメソッドをコールする
  4. flush()メソッドを使用して変換結果をフラッシュする

リスト2にCharset#encodeメソッドと一括変換を行うCharsetEncoder#encodeメソッドの例を示します。また、リスト3に逐次変換を行うCharsetEncode#encodeの例を示します。

リスト 2 char列からbyte列への一括変換

    CharBuffer chbuf = CharBuffer.wrap("あいうえおかきくけこ");
 
    Charset charset = Charset.forName("Shift_JIS");
    CharsetEncoder encoder = charset.newEncoder();
    
    // Charset#encode を使用
    ByteBuffer result1 = charset.encode(chbuf);
    // CharsetEncoder#encode を使用
    ByteBuffer result2 = encoder.encode(chbuf);

 

リスト 3 char列からbyte列への逐次変換

    CharBuffer[] chbufs = new CharBuffer[3] {
                  CharBuffer.wrap("あいうえおかきくけこ"),
                  CharBuffer.wrap("さしすせそたちつてと"),
                  CharBuffer.wrap("なにぬねのはひふへほ") };
 
    Charset charset = Charset.forName("Shift_JIS");
    CharsetEncoder encoder = charset.newEncoder();
 
    ByteBuffer bybuf = ByteBuffer.allocate(50);

    encoder.reset();
    int i;
    for (i = 0 ; i < chbufs.length  -1 ; i++) {
        encoder.encode(chbufs[i], bybuf, false);
    }
    encoder.encode(chbufs[i], bybuf, true);
    encoder.flush(bybuf);

byte列からchar列への変換

public CahrBuffer decode(ByteBuffer bb)
public CharBuffer decode(ByteBuffer in)
public CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)

char列からbyte列に変換するdecodeメソッドもCharsetクラスとCharsetDecoderクラスの両方に定義されており、encodeメソッドと同様にCharsetクラスで定義されたものは簡易メソッドです。

CharsetDecoderで定義されているdecodeメソッドはencodeと同様に一括変換と逐次変換の両方をサポートしています。逐次変換の使用法はencodeの場合と同じです。

リスト4にCharset#decodeメソッドと一括変換を行うCharsetDecoder#decodeメソッドの例を示します。また、リスト5は逐次変換の例です。

リスト 4 byte列からchar列への一括変換

    ByteBuffer bybuf = ByteBuffer.wrap(
          new byte[]{0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4});
 
    Charset charset = Charset.forName("Shift_JIS");
    CharsetDecoder decoder = charset.newDecoder();
    
    // Charset#decode を使用
    CharBuffer result1 = charset.decode(bybuf);
    // CharsetDecoder#decode を使用
    CharBuffer result2 = decoder.decode(bybuf);

 

リスト 5 byte列からchar列への逐次変換

    ByteBuffer[] bybufs = new ByteBuffer[3] {
          ByteBuffer.wrap(new byte[]{0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4}),
          ByteBuffer.wrap(new byte[]{0x82, 0xa6, 0x82, 0xa8, 0x82, 0xa9}),
          ByteBuffer.wrap(new byte[]{0x82, 0xab, 0x82, 0xad, 0x82, 0xaf}) };
 
    Charset charset = Charset.forName("Shift_JIS");
    CharsetEncoder encoder = charset.newEncoder();

    CharBuffer chbuf = CharBuffer.allocate(50);

    decoder.reset();
    int i;
    for (i = 0 ; i < bybufs.length  -1 ; i++) {
        decoder.decode(bybufs[i], chbuf, false);
    }
    
    decoder.decode(bybufs[i], chbuf, true);
    decoder.flush(chbuf);

(2003.03)