2010年2月26日金曜日

Javaのデータ読み書き

Javaでなんらかのデータを読み書きするとき(たとえばテキストファイルの読み書きや、画像データの読み書き、ネットワークデータのやり取りなどなど)はストリーム系のクラス群(java.io.*)を使用する必要がある。ここではそれらの基本的なコードをまとめてみる。

ストリームの種類

ストリームには大別すると2種類あって、バイトと文字がある。

  • バイトストリーム
    • InputStream
    • OutputStream
  • 文字ストリーム
    • Reader
    • Writer
これらのクラスはストーリムを扱うトップレベルのスーパークラスであり一番重要。

InputStreamのサンプル

引数で与えられたファイルのバイト数を返す。FileInputStreamについては後述。
import java.io.*;                                   
class InputStreamSample {                           
    public static void main(String[] args)          
    {                                               
        InputStream in = null;                      
        try {                                       
            if (args.length == 0)                   
                in = System.in;                     
            else                                    
                in = new FileInputStream(args[0]);  
            int total = 0;                          
            while (in.read() != -1)                 
                total++;                            
            System.out.println(total + " bytes");   
        } catch (IOException e) {                   
            e.printStackTrace();                    
        } finally {                                 
            try {                                   
                if (in != null) {                   
                    in.close();                     
                }                                   
            } catch (IOException e) {               
            }                                       
        }                                           
    }                                               
}                                                   

OutputStreamのサンプル

引数を2つ必要とし、第1引数に変換前の文字、第2引数に変換後の文字をいれる。
その後入力待ち状態となり、入力した文字を変換しながら表示する。
import java.io.*;
class OutputStreamSample {
    public static void main(String[] args)
    {
        // charAt(0):0番目の文字コードを取得
        byte from = (byte) args[0].charAt(0);
        byte to = (byte) args[1].charAt(0);
        int b = 0;
        try {
            while ((b = System.in.read()) != -1)
                System.out.write(b == from? to: b);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


ファイルの読み書き

文字ストリームとバイトストリームには、それぞれにFileから読み込むためのクラスがある。
  • バイト
    • FileInputStream
    • FileOutputStream
  • 文字
    • FileReader
    • FileWriter

/*Reader*/


バッファリング

データの読み書きは前述のように大抵ファイルかネットワークでこれらはメモリより全然遅い。
前述のクラスは、1バイト単位、1文字単位で読み込むことになり効率が悪い。
そこで、ほとんどのケースでバッファリングクラスを介して前述のクラスを使用する。
  • バイトストリーム
    • BufferdInputStream
    • BufferdOutputStream
  • 文字ストリーム
    • BufferdIReader
    • BufferdIWriter

ストリーム系クラスは、インスタンス生成時にどんどんくるむ。これをデコレータパターンという。
典型的な例。
/* ここにコード例 */

注意すべきは、ストリームをクローズするときは、その一番外側のクラスだけをクローズすればよいということ。
closeが失敗するのはディスクフルの書き込み失敗ぐらいで、読み込みじにクローズが失敗することは殆どない。
基本的に必ずfinally句に書くようにすれば良い。
/* ここにコード例 */

データ読み書きで使用するクラス

/* ここに主に使用するクラスの関係図 */

0 件のコメント: