Writer・Bufferクラス

ファイルも、文字列も同じ扱い

FileWriter・FileReaderクラスについて説明してきましたが、ファイルの読み書き・書き込みの操作は、一文字ずつ入行わなくてはならないため、使い勝手は今一つです。そこで、ここでは様々なクラスを使って、そいうった操作をより洗練させていく方法を紹介します。

まず最初に紹介するのはBufferedWriter・ BufferedReaderクラスで、これらはある程度データをまとめて(溜めて)から、一度に入出力(読み書き)をおこなうためのクラスです。これによりある程度まとめて入出力を行うことができるため、処理速度を向上させることができます。

BufferedWriter・BufferedReader

ファイルの読み込み・書き込み

では実際に、BufferedWriter・BufferedReaderクラスのサンプルを見てみましょう。これらのクラスはFileWriterクラス ・ FileReaderクラスを利用している(ラップしている)だけで、ファイルの扱いが格段にしやすくなることに着目してください。

ClassSample01.java
package class2;

import java.io.*;

public class ClassSample1 {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		BufferedWriter bw = null;
		BufferedReader br = null;
		String FileName = "filesample2.txt";
		try{
			bw = new BufferedWriter(new FileWriter(FileName));
			bw.write("もも¥r¥n");
			bw.write("うめ¥r¥n");
			bw.write("さくら¥r¥n");
			bw.flush();							//ここでフラッシュ
			br = new BufferedReader(new FileReader(FileName));
			String s;							//文字列型に代入できる
			while((s = br.readLine()) != null){			//何も無かったらnullが返る
					System.out.println(s);
			}
		}catch(FileNotFoundException e1){
			System.out.println("ファイルエラーです。");
		}catch(IOException e2){
			System.out.println("IOエラーです。");
		}finally{
			try{		//close()もIOExceptionをスローする
				if(bw != null) bw.close();
				if(br != null) br.close();
			}catch(IOException e){
				System.out.println("クローズ失敗");
			}
		}
	}

}
実行結果
もも
うめ
さくら

図2-1.filesample2.txtの中身

filesample2.txtの中身

このプログラムでは、いったんファイルへの書き込みを行い(filesample2.txt/図2-1.)、そのあとそのファイルを読み込んで表示しています。今まで文字コードで返って来るのでint型で受けてそれをchar型へ型変換していましたが、BufferedReaderクラスのreadLine()メソッドは1行毎にテキストを読み込みます。

これにより、FileReaderクラス単独で読み込みを行ってきた時よりも、はるかに簡単にデータの読み書きができていることがわかります。

プログラムの内容

BufferedWriteクラスを用いてファイルにテキストデータを書き込む場合、13行目のように、FileWriterクラスを生成し、それをラッピングしてBufferedWriterクラスを生成します。

BufferdWriterクラスで、FileWriterクラスをラップする
bw = new BufferedWriter(new FileWriter(FileName));

すると、BufferdWriterクラスのインスタンスであるbwのwrite()メソッドを呼び出すことによって、ファイルにデータを書き込むことになります。最終的に、flush()メソッドを実行すると、write()したデータが、ファイルに書き込まれます。(18行目)

ファイルの読み取は、BufferedReaderクラスを用います。18行目で行っているように、FileReaderクラスを生成し、それをラッピングしたBufferedReaderクラスのインスタンスを生成すると、そのインスタンスでファイルの読み出しができます。

BufferdReaderクラスで、FileReaderクラスをラップする
br = new BufferedReader(new FileReader(FileName));

20行目に出てくる、BufferedReaderのreadLine()メソッドは、テキストデータの1行を読み取れます。nullが帰ってくれば、読み出しは終了します。これにより、BufferedWriter、BufferedReaderクラスのメソッドによってファイルの書き込み・読み込みができるようになります。

コンソールからの文字の読み出し

BufferedReaderでコンソールから文字列入力

BufferedReader/Writerクラスの使い方は、何もファイルに限ったことではありません。次のサンプルでは、BufferedReaderクラスを利用して、コンソールから文字列の入力を行っています。実際に打ち込んで実行してみてください。

ClassSample02.java
package class2;

import java.io.*;

public class ClassSample2 {

	public static void main(String[] args) {
		BufferedReader br = null;
		try{
			br = new BufferedReader(new InputStreamReader(System.in));
			while(true){
				String s;
				System.out.print("InputData(q : finish) : ");
				s = br.readLine();
				//	qが入力されたら終わり
				if(s.equals("q")){
					break;
				}
				System.out.println("Input Data:" + s);
				System.out.println();
			}
		}catch(IOException e2){
			System.out.println("IOエラー");
		}finally{
			try{
				if(br != null) br.close();
			}catch(IOException e){
				System.out.println("IOエラー");
			}
		}
	}

}
実行結果

InputData(q : finish) : abcdefg
Input Data:abcdefg

InputData(q : finish) : hijeklmno
Input Data:hijeklmno

InputData(q : finish) : q

プログラムを実行すると、「InputData(q : finish) :」と表示され、コンソールから文字列の入力を促す画面が出現します。ここに文字列を入力すると、その入力した文字列が表示されます。ただし、「q」を入力すると、そこでプログラムは終了します。

ファイルの書き込み・読み込み

プログラムの仕組み

このプログラムでは、Systemクラスのinフィールドを、InputStreamReaderクラスでラップし、更にInputStreamReaderクラスをBufferedReaderクラスでラップしています。

Systemクラスのinフィールドのラッピング
br = new BufferedReader(new InputStreamReader(System.in));

これにより、BufferedReaderクラスのreadLine()メソッドを読みだすと、コンソールから文字列を読みだすようにプログラムが変わります。同じBufferdReaderでもラップするクラスを変えると、処理が全く変わるのです。あとは、qが入力されるまで、同じ処理を繰り返しています。

eclipseで日本語を扱う場合の問題

このサンプルをeclipseで実行する場合、英数字ならば問題はないのですが、日本語を入力する場合は文字を入力した後にEnterを押して、そのまま文字を入力しないでください。再度実行するまで何も出来なくなります。この例では『:』の後ろにカーソルをマウスやキーボードで、移動してから文字を入力する必要があります。