Javaサンプルコード辞典

CharsetDecoder,CharBuffer - Shift_JISのテキストファイルを読み込み、標準出力に表示する

「FileChannel」から「ByteBuffer」に読み込んだバイトを「CharsetDecoder」でchar型にデコードします。

ByteBufferに読み込んだバイトを文字型に変換する処理は、CharsetDecoderで行います。シフトJIS形式のテキストファイルから文字列を読み込んだ場合、2バイト文字の1バイトを読み込んだ時点で、ByteBufferの容量に達してしまう場合があります。その場合、CharsetDecoderのdecode()メソッドの戻り値、CoderResultのisMalformed()がtrueを返しますので、読み込んだバイト数+1のサイズを持つバッファにもう一度読み直しを行ってデコードを行います。
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CoderResult;

//Shift_JISのテキストファイルを読み込み、標準出力に表示する
public class DecodeChar {

      public static void main(String[] args) {
            
            System.out.println("--処理開始--");
            
            //コマンドライン引数が入力されているかチェックを行う
            if(args.length == 0)
            {
                  System.out.println("コマンドライン引数を指定してください");
                  return;
            }
            
            //ファイル入力用チャネル
            FileChannel inChannel = null;
            
            //Shift_JISの文字コードセットを取得する
            Charset charset = Charset.forName("Shift_JIS");
            //Shift_JIS用のデコーダーを取得する
            CharsetDecoder decoder = charset.newDecoder();
            
            //読み込んだ文字列を格納するStringBuffer
            StringBuffer sb = new StringBuffer();
            
            try
            {
                  //ファイル入力用ストリームからチャネルを取得する
                  FileInputStream in = new FileInputStream(args[0]);
                  inChannel = in.getChannel();
                  
                  //割り当てられたバッファのサイズずつ入力チャネルから
                  //読み込んでいくと、2バイト文字の1バイト目を読み込んで
                  //読み込みが終了してしまう場合がある。
                  //その場合は、奇数バイトのバッファに読み直しを行う
                  
                  //偶数読み込みの場合のバッファを割り当てる
                  ByteBuffer evenBuff = ByteBuffer.allocateDirect(1024);
                  //偶数読み込みの場合の文字バッファを割り当てる
                  CharBuffer evenCBuff = CharBuffer.allocate(1024);
                  
                  //奇数読み込みの場合のバッファを割り当てる
                  ByteBuffer oddBuff = ByteBuffer.allocateDirect(1025);
                  //奇数読み込みの場合の文字バッファを割り当てる
                  CharBuffer oddCBuff = CharBuffer.allocate(1025);
                  
                  //チャネルの現在位置
                  long position = 0;

                  //チャネルからバイトを読み込みバッファに格納する
                  //ファイルの終端に達したら-1が返却されるのでループを抜ける
                  //偶数バイトの読み込みを行う
                  while(inChannel.read(evenBuff,position) != -1)
                  {
                        //リミットを現在位置に設定し、現在位置を0に戻す
                        evenBuff.flip();                        
                        
                        //読み込んだ偶数のバイト配列をデコードする
                        //第1引数は入力となるバイトバッファ、第2引数は出力先の文字バッファ
                        //第3引数は入力バッファにさらにバイトが追加される可能性が
                        //あるか否か                        
                        CoderResult result = decoder.decode(evenBuff, evenCBuff, true);
                        
                        //偶数バイトの読み込みでデコードエラーが発生した場合
                        //奇数バイトを読み直す
                        if(result.isMalformed())
                        {
                              //奇数のバイト配列を読み直す
                              inChannel.read(oddBuff,position);
                              
                              //リミットを現在位置に設定し、現在位置を0に戻す
                              oddBuff.flip();
                              
                              //読み込んだ奇数のバイト配列をデコードする
                              //第1引数は入力となるバイトバッファ、第2引数は出力先の文字バッファ
                              //第3引数は入力バッファにさらにバイトが追加される可能性が
                              //あるか否か
                              decoder.decode(oddBuff, oddCBuff, true);
                              
                              //リミットを現在位置に設定し、現在位置を0に戻す
                              oddCBuff.flip();
                              
                              //読み込んだ文字列をStringBufferに追加する
                              sb.append(oddCBuff.toString());
                              
                              //チャネルの読み込み位置を進める
                              position += oddBuff.capacity();
                              
                              oddBuff.clear();
                              oddCBuff.clear();
                              
                        }
                        else
                        {
                              //リミットを現在位置に設定し、現在位置を0に戻す
                              evenCBuff.flip();
                        
                              ////読み込んだ文字列をStringBufferに追加する
                              sb.append(evenCBuff.toString());
                              
                              //チャネルの読み込み位置を進める
                              position += evenBuff.capacity();
                        }
                        
                        //バッファをクリアする
                        evenBuff.clear();
                        evenCBuff.clear();
                  }
                  
                  System.out.println(sb.toString());
            }
            catch(IOException e)
            {
                  System.out.println(e);
            }
            finally
            {
                  if(inChannel != null)
                  {
                        try
                        {
                              inChannel.close();
                        }catch(Exception e){ System.out.println(e); }
                  }
            }
            
            System.out.println("--処理終了--");
      }

}

(2007年11月3日)  

 ちょっと一休み. Javaキーワード並び替えゲーム

画面に表示される文字列を並び替えるとJavaに関連するキーワードになります。ヒントをたよりに並び替えを行ってエンターを押してください。 ユーザ登録をしてログインするとランキングに参加できます。
Flex Tips

DWRでリッチなWebページを作る!

Java Tips  java.io 編

Java Tips  java.lang 編