Reader型
Reader 型の利用方法
まずは,入力を扱うReader
を利用する方法を確認します.Reader
と一口に言っても,
以下のように多くの型がReader
型には存在します.
FileReader
- ファイル(
File
型)からテキストデータを読み込むためのReader
型.
- ファイル(
BufferedReader
- バッファリングを行うための
Reader
型. - データソースから行単位で文字列を読み込める.
- 他の
Reader
は文字単位でしかデータを読み込めない.
- 他の
- バッファリングを行うための
StringReader
- 文字列(
String
型)からテキストデータを読み込むためのReader
型.
- 文字列(
LineNumberReader
- 読み込んだ行数を数える
Reader
型.
- 読み込んだ行数を数える
InputStreamReader
InputStream
型の入力ストリームをReader
型に変換するReader
型.
ここに挙げた以外にもいくつかのReader
型が存在しますが,この講義では,FileReader
とBufferedReader
,そして,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
)します.
次に,構築した FileReader
をBufferedReader
に渡し,
行単位で読み込めるBufferedReader
を構築します.
そして,1 行ずつ読み込むには,BufferedReader
型が持つreadLine
メソッドを
呼び出します.readLine
メソッドは,1 行読み込み,その結果をString
型で返します.
もう読み込めるデータがない場合は,null
を返します.
そのため,while((line = in.readLine()) != null)
という繰り返しで最後まで順に読み込めるようになります.
最後にこれ以上ストリームを利用しないため,close
メソッドを呼び出します.close
メソッドは一番外側のReader
に対してだけ呼び出せば良いです.
ラップされているReader
は外側のReader
が閉じられると,自動的に閉じられます.
入出力を扱うには,必ず IOException
という検査例外に対応しなければいけません.
どこかで入出力エラーが起こる可能性が排除できないためです.
そのため,メソッドのシグネチャに,throws 節を追加しています.
もちろん,readMethod
メソッドを呼び出しているメソッドにも throws
節で,IOException
の責任を転嫁してください.
この点に不安がある人は,[例外機構](/2022spring /lesson06/animation#例外機構 exception-architecture)を復習してください.
ただし,FileReader
に渡すファイルが存在しない場合
(exists
メソッドがfalse
を返す場合),FileNotFoundException
という例外が投げられます.
なお,FileNotFoundException
はIOException
としても扱えますので,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.*;
...途中省略
}