Writer・Bufferクラス
ファイルも、文字列も同じ扱い
FileWriter・FileReaderクラスについて説明してきましたが、ファイルの読み書き・書き込みの操作は、一文字ずつ入行わなくてはならないため、使い勝手は今一つです。そこで、ここでは様々なクラスを使って、そいうった操作をより洗練させていく方法を紹介します。
まず最初に紹介するのはBufferedWriter・ BufferedReaderクラスで、これらはある程度データをまとめて(溜めて)から、一度に入出力(読み書き)をおこなうためのクラスです。これによりある程度まとめて入出力を行うことができるため、処理速度を向上させることができます。
BufferedWriter・BufferedReader
ファイルの読み込み・書き込み
では実際に、BufferedWriter・BufferedReaderクラスのサンプルを見てみましょう。これらのクラスはFileWriterクラス ・ FileReaderクラスを利用している(ラップしている)だけで、ファイルの扱いが格段にしやすくなることに着目してください。
ClassSample01.javapackage 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.javapackage 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を押して、そのまま文字を入力しないでください。再度実行するまで何も出来なくなります。この例では『:』の後ろにカーソルをマウスやキーボードで、移動してから文字を入力する必要があります。