ファイルからテキスト(普通の文字のあつまり)を行単位で入力するには、FileReader(ファイル名) と BufferedReader(ストリーム) というクラスを組み合わせて使います。
次のようにします。
import java.io.*; public class FileRead { public static void main(String[] args){ String fname =args[0]; int ct = 0; try { FileReader in = new FileReader(fname); BufferedReader inb = new BufferedReader(in); String line; ct = 0; while ((line = inb.readLine()) != null) { ct++; System.out.println(line); } System.out.println("以上" + ct + "行"); inb.close(); in.close(); } catch (IOException e) { System.err.println( fname + " がないのでは?" ); System.err.println( e); } } }
new FileReader(ファイル名) でファイル名を引数として、ファイルをテキストとしてひらくためのオブジェクトが作成されます。それに、in という名前を付けています。ファイルの表紙を開いて中身を読む直前までの用意ができました。この後 in というオブジェクトを通してファイルを読みます。
しかし、このままでは1文字ずつしか読むことができないので不便です。
そこで、in からの入力を BufferedReader(in) を通すことにします。このバッファによって1行ずつ読んでいくことができるようになります。
new BufferedReader(in) で in を引数としてバッファ付きのリーダのオブジェクトを作成し、安易ですが、inb という名前にしています。以降は inb を通してファイルを読むと、in から読まれたデータが inb も通って入ってきます。
入出力ではこのようにいろいろな機能を持ったクラス(のインスタンス)を直列につないで使用することがよくあります。
この~Readerは使い終わったらcloseをします。
closeの順番は作った順序と逆にします。
2つめの inb を使うようになると in を使うことはまずありませんので、in という名前は特になくてもいいのです。そこで、次のようにまとめて書くこともできます。
BufferedReader inb = new BufferedReader(new FileReader(fname));
この場合はcloseは1つでまとめてやります。
inb.close();
ファイルから1行単位で読むには、inb.readLine() というメソッドを使います。inb に対して .readLine() と命令しているようすをイメージします。
入力された1行は 文字変数 line に代入されています。
もし、ファイルが最後まで読まれてしまった場合、inb.readLine() は null を返します。これはもうファイルが空だというサインです。
したがって、whileの( )の中は、「ファイルが空になっていないうち」という条件で繰り返されます。
たとえば,aa.txt を引数に実行してみます。aa.txtがないのでcatchに捕まって例外処理が行われます。
$ java FileRead aa.txt aa.txt がないのでは? java.io.FileNotFoundException: aa.txt (指定されたファイルが見つかりません。)
存在するテキストファイルをたとえば,toi01.txt を引数にすればその内容が表示されます。
$ java FileRead toi01.txt (1) int int ○ ○ (2) int double × × (3) float double × × (4) float int × ○ (5) double long × ○ (6) double double ○ ○ 以上6行
FileRead.java をつくり実行してみなさい
引数にjavaフォルダー内に存在するファイルを指定しないとうまくいきません。エディタを使って適当なテキストファイルを作って表示してみるのもよいでしょう。