Javaでテキストファイルを読み込む方法は複数あり、ファイルのサイズや用途で使い分けます。さらに日本語を扱うなら文字コードの指定が重要で、これを怠るとUTF-8のファイルが文字化けします。この記事では代表的な方法と、文字化けを防ぐポイントを解説します。
この記事の結論:行単位で省メモリに読むなら
BufferedReader、小さいファイルを一括で読むなら Files.readAllLines() / Files.readString()。日本語では文字コードに StandardCharsets.UTF_8 を明示しないと文字化けします。最重要:文字コードを指定しないと日本語が文字化けする
よくある落とし穴が FileReader です。FileReader はプラットフォーム既定の文字コードで読むため、Windows(既定がMS932/Shift-JIS系)でUTF-8のファイルを読むと文字化けします。必ず文字コードを明示しましょう。
new FileReader(file) や new Scanner(file) は文字コードを指定できない(または既定に依存する)ため、環境によって日本語が化けます。InputStreamReader や Files 系でStandardCharsets.UTF_8 を明示するのが安全です。BufferedReader:行単位で省メモリに読む
大きなファイルでも1行ずつ処理でき、メモリ効率が良い方法です。文字コードを指定するため InputStreamReader を挟みます。try-with-resources で確実に閉じます。
BufferedReader(UTF-8明示)
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("example.txt"), StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Filesクラス:手軽に一括で読む(Java 7+)
Files.readAllLines() は全行をリストで、Files.readString()(Java 11+)はファイル全体を1つの文字列で読み込みます。小さいファイル向きで、コードが簡潔です。文字コードも指定できます。
Files.readAllLines / readString
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
Path path = Paths.get("example.txt");
// 全行をリストで(charset明示)
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
lines.forEach(System.out::println);
// ファイル全体を1つの文字列で(Java 11+)
String text = Files.readString(path, StandardCharsets.UTF_8);
System.out.println(text);
}
}
Files.readAllLines() や readString() はファイル全体をメモリに読み込みます。巨大なファイルではメモリ不足になるため、その場合は次の Files.lines() やBufferedReader で1行ずつ処理してください。Files.lines:大きなファイルをストリームで処理(Java 8+)
Files.lines() は行をStreamで遅延読み込みするため、大きなファイルでもメモリを抑えて処理できます。Streamは閉じる必要があるので try-with-resources を使います。
Files.lines(大容量・Stream)
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) throws IOException {
Path path = Paths.get("big.txt");
try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) {
stream.filter(line -> line.contains("ERROR"))
.forEach(System.out::println);
}
}
}
Scanner:解析しながら読む
Scanner は行・単語・数値などを解析しながら読むのに向いています。文字コードを指定できるコンストラクタを使いましょう。
Scanner(charset指定)
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
try (Scanner sc = new Scanner(new File("example.txt"), StandardCharsets.UTF_8)) {
while (sc.hasNextLine()) {
System.out.println(sc.nextLine());
}
}
}
}
方法の使い分け
| 方法 | 向いている場面 |
|---|---|
BufferedReader |
行単位・省メモリ(汎用) |
Files.readAllLines / readString |
小さいファイルを一括で |
Files.lines |
大きいファイルをStreamで |
Scanner |
単語・数値などを解析しながら |
よくある質問(FAQ)
Q読み込んだ日本語が文字化けします。
AFileReaderなど文字コードを指定していないことが原因です。Windowsでは既定がUTF-8でないため、UTF-8ファイルが化けます。
StandardCharsets.UTF_8 を明示できる InputStreamReader や Files 系を使ってください。Q大きなファイルを読むとメモリ不足になります。
A
Files.readAllLines() や readString() は全体をメモリに載せるためです。Files.lines() や BufferedReader で1行ずつ処理すれば省メモリです。Qファイル全体を1つの文字列で読みたいです。
AJava 11以降なら
Files.readString(path, StandardCharsets.UTF_8) が簡潔です。それ以前は String.join("\n", Files.readAllLines(path, charset)) などで代用します。QBufferedReaderとScannerはどちらが良いですか?
A単に行を読むだけなら
BufferedReader が高速・省メモリで定番です。単語・数値などを解析しながら読むなら Scanner が便利です。まとめ
Javaのファイル読み込みのポイントを整理します。
- 文字コードは
StandardCharsets.UTF_8を明示(FileReaderは化ける) - 行単位・省メモリは
BufferedReader - 小さいファイルは
Files.readAllLines/readString(Java 11) - 大きいファイルは
Files.lines(Stream)で1行ずつ - 解析しながら読むなら
Scanner。リソースは try-with-resources で閉じる
関連として、ファイルに書き込む方法・CSVファイルを読み込む方法・catchブロック・例外処理もあわせて読むと、JavaのファイルI/Oに強くなれます。
