new BufferedReader() / リーダー.readLine()
| 対応: | Java 1.0(1996) |
|---|
『BufferedReader』はテキスト入力をバッファリングして効率よく読み取るクラスです。ファイルや標準入力を1行ずつ読み取る際に使われます。Java 7以降の try-with-resources 構文と組み合わせることで、クローズ処理を自動化できます。
構文
// 標準入力を読み取る BufferedReader を作成します
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// ファイルを読み取る BufferedReader を作成します
BufferedReader reader = new BufferedReader(new FileReader("ファイルパス"));
// 1行読み取ります(ファイル末尾では null を返します)
String line = reader.readLine();
メソッド一覧
| クラス・メソッド | 概要 |
|---|---|
| new BufferedReader(Reader) | 指定した Reader をラップしてバッファリングを追加します。 |
| new InputStreamReader(InputStream) | バイトストリームを文字ストリームに変換します。文字コードの指定も可能です。 |
| readLine() | 1行を文字列として読み取ります。行末の改行文字は含みません。ファイル末尾に達した場合は null を返します。 |
| lines() | 全行を Stream<String> として返します(Java 8+)。ストリーム処理と組み合わせて使えます。 |
| close() | ストリームを閉じます。try-with-resources 構文で自動的に呼び出されます。 |
サンプルコード
BufferedReaderExample.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
class BufferedReaderExample {
public static void main(String[] args) throws IOException {
// 標準入力から1行読み取ります
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
System.out.print("入力してください: ");
String line = reader.readLine();
System.out.println("入力値: " + line);
} catch (IOException e) {
e.printStackTrace();
}
// ファイルを1行ずつ読み取ります
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// lines() でストリームとして処理します(Java 8+)
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
br.lines()
.filter(l -> !l.isEmpty())
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
コンパイルして実行すると次のようになります。
javac BufferedReaderExample.java java BufferedReaderExample 入力してください: こんにちは 入力値: こんにちは 夜神月 エル 弥海砂 夜神月 弥海砂
よくあるミス
よくあるミス1: close()忘れでリソースリーク
BufferedReaderを使い終わった後にclose()を呼ばないと、ファイルハンドルが解放されずリソースリークが発生します。夜神月がデスノートを使い終わっても処分しないようなものです。
ReaderLeakNg.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class ReaderLeakNg {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("sample.txt"));
String line = br.readLine();
System.out.println(line);
}
}
コンパイルして実行すると次のようになります。
javac ReaderLeakNg.java java ReaderLeakNg 夜神月
try-with-resources構文を使うと、ブロック終了時に自動的にclose()が呼ばれます。エル/Lが証拠を確実に処理するように、リソースも確実に閉じてください。
ReaderLeakOk.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class ReaderLeakOk {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
String line = br.readLine();
System.out.println(line);
}
}
}
コンパイルして実行すると次のようになります。
javac ReaderLeakOk.java java ReaderLeakOk 夜神月
よくあるミス2: readLine()のnull戻り値チェック忘れでNullPointerException
『readLine()』はファイルの末尾に達すると『null』を返します。nullチェックを忘れると、ファイルの末尾でNullPointerExceptionが発生します。弥海砂がミサミサのポーズを決める前に、まずnullチェックを確認してください。
ReadLineNullNg.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class ReadLineNullNg {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
String line = br.readLine();
System.out.println(line.toUpperCase());
}
}
}
コンパイルして実行すると次のようになります。
javac ReadLineNullNg.java java ReadLineNullNg Exception in thread "main" java.lang.NullPointerException
ニアが慎重に推理するように、readLine()の戻り値は必ずnullチェックをしてから使用してください。
ReadLineNullOk.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class ReadLineNullOk {
public static void main(String[] args) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line.toUpperCase());
}
}
}
}
コンパイルして実行すると次のようになります。
javac ReadLineNullOk.java java ReadLineNullOk YAGAMI LIGHT L LAWLIET AMANE MISA
概要
『BufferedReader』は内部バッファを持つため、1文字ずつ読み込む FileReader 単体と比べて大幅に高速です。readLine() はファイル末尾で null を返すため、null チェックを while 条件に含めてください。
Java 7以降の try-with-resources 構文(try (BufferedReader br = ...))を使うと、ブロック終了時に自動的に close() が呼ばれます。明示的な close() の呼び忘れを防ぐためにも積極的に使用してください。
ファイル全体をまとめて読み込む方法については『Files.readString() / Files.readAllLines()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。