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/図2-1.)、そのあとそのファイルを読み込んで表示しています。今まで文字コードで返って来るのでint型で受けてそれをchar型へ型変換していましたが、BufferedReaderクラスのreadLine()メソッドは1行毎にテキストを読み込みます。
これにより、FileReaderクラス単独で読み込みを行ってきた時よりも、はるかに簡単にデータの読み書きができていることがわかります。
プログラムの内容
BufferedWriteクラスを用いてファイルにテキストデータを書き込む場合、13行目のように、FileWriterクラスを生成し、それをラッピングしてBufferedWriterクラスを生成します。
BufferdWriterクラスで、FileWriterクラスをラップするすると、BufferdWriterクラスのインスタンスであるbwのwrite()メソッドを呼び出すことによって、ファイルにデータを書き込むことになります。最終的に、flush()メソッドを実行すると、write()したデータが、ファイルに書き込まれます。(18行目)
ファイルの読み取は、BufferedReaderクラスを用います。18行目で行っているように、FileReaderクラスを生成し、それをラッピングしたBufferedReaderクラスのインスタンスを生成すると、そのインスタンスでファイルの読み出しができます。
BufferdReaderクラスで、FileReaderクラスをラップする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フィールドのラッピングこれにより、BufferedReaderクラスのreadLine()メソッドを読みだすと、コンソールから文字列を読みだすようにプログラムが変わります。同じBufferdReaderでもラップするクラスを変えると、処理が全く変わるのです。あとは、qが入力されるまで、同じ処理を繰り返しています。
eclipseで日本語を扱う場合の問題
このサンプルをeclipseで実行する場合、英数字ならば問題はないのですが、日本語を入力する場合は文字を入力した後にEnterを押して、そのまま文字を入力しないでください。再度実行するまで何も出来なくなります。この例では『:』の後ろにカーソルをマウスやキーボードで、移動してから文字を入力する必要があります。









