Reader型

Reader型の利用方法

まずは,入力を扱うReaderを利用する方法を確認します.Readerと一口に言っても, 以下のように多くの型がReader型には存在します.

  • FileReader
    • ファイル(File型)からテキストデータを読み込むためのReader型.
  • BufferedReader
    • バッファリングを行うためのReader型.
    • データソースから行単位で文字列を読み込める.
      • 他の Readerは文字単位でしかデータを読み込めない.
  • StringReader
    • 文字列(String型)からテキストデータを読み込むためのReader型.
  • LineNumberReader
    • 読み込んだ行数を数えるReader型.
  • InputStreamReader
    • InputStream型の入力ストリームをReader型に変換するReader型.

ここに挙げた以外にもいくつかのReader型が存在しますが,この講義では,FileReaderBufferedReader,そして,InputStreamReaderの3つの型を扱います.

また,それぞれの型を利用するには,それぞれの型のインポートが必要です. 例えば,BufferedReaderを利用するときには,import java.io.BufferedReader;という一文が クラス宣言の前に必要です.

典型的なファイルからのデータの読み込み方法.

void readMethod(File file) throws IOException{
  BufferedReader in = new BufferedReader(new FileReader(file)); // (1)
  // 上記の(1)の処理を区別して書くと,次のような処理になる.
  //     FileReader freader = new FileReader(file);
  //     BufferedReader in = new BufferedReader(freader);
  String line;
  while((line = in.readLine()) != null){
    // 1行ずつ処理を行う.
  }
  in.close();
}

ファイルからデータを1行ずつ読み込む典型的な方法は,上記の通りです. まず FileReaderを利用してファイルから読み込むための Readerを構築(new)します. 次に,構築した FileReaderBufferedReaderに渡し, 行単位で読み込めるBufferedReaderを構築します.

そして,1行ずつ読み込むには,BufferedReader型が持つreadLineメソッドを 呼び出します.readLineメソッドは,1行読み込み,その結果をString型で返します. もう読み込めるデータがない場合は,nullを返します. そのため,while((line = in.readLine()) != null) という繰り返しで最後まで順に読み込めるようになります.

最後にこれ以上ストリームを利用しないため,closeメソッドを呼び出します.close メソッドは一番外側のReaderに対してだけ呼び出せば良いです. ラップされているReaderは外側のReaderが閉じられると,自動的に閉じられます.

入出力を扱うには,必ず IOExceptionという検査例外に対応しなければいけません. どこかで入出力エラーが起こる可能性が排除できないためです. そのため,メソッドのシグネチャに,throws節を追加しています. もちろん,readMethodメソッドを呼び出しているメソッドにも throws 節で,IOExceptionの責任を転嫁してください.

この点に不安がある人は,例外機構を復習してください.

ただし,FileReaderに渡すファイルが存在しない場合 (existsメソッドがfalseを返す場合),FileNotFoundExceptionという例外が投げられます. なお,FileNotFoundExceptionIOExceptionとしても扱えますので,throws 節はIOExceptionのみで問題ありません.

1文字単位の読み込み

1行単位で読み込むには,典型的なファイルからのデータの読み込み方法のようなプログラムで可能です. 一方で,1文字単位で読み込みたい場合もあります. その場合の典型例を以下に示します.

void readMethod(String targetFile) throws IOException{
  FileReader in = new FileReader(targetFile); // File型でもString型でもOK
  Integer read;
  while((read = in.read()) != -1){
    // 1文字単位で読み込む.この場合,ラッピングはしてもしなくてもOK.
  }
  in.close();
}

Javaの Reader 型には,1文字単位で読み込むメソッドreadが用意されています. 読み込んだ文字を Integer 型で返します. 読み込むデータがもう存在しない場合は,-1が返されますので,その間繰り返す,というプログラムになっています.

例題1. Catコマンドの作成

コマンドラインで指定されたテキストファイルの内容を表示するコマンド Catを作成してください. この例題では,コマンドライン引数が与えられなかった場合は考える必要はありません.

実行例

$ cat Cat.java
import java.io.*;
    ...途中省略
}
$ java Cat Cat.java
import java.io.*;
    ...途中省略
}