【Java】ファイルを読み込む方法|BufferedReader・Filesと文字コードの注意

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) は文字コードを指定できない(または既定に依存する)ため、環境によって日本語が化けます。InputStreamReaderFiles 系で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());
            }
        }
    }
}
書き込みはファイルに書き込む方法、CSVの読み込みはCSVファイルを読み込む方法、例外処理の基本はcatchブロック・例外処理を参照してください。

方法の使い分け

方法 向いている場面
BufferedReader 行単位・省メモリ(汎用)
Files.readAllLines / readString 小さいファイルを一括で
Files.lines 大きいファイルをStreamで
Scanner 単語・数値などを解析しながら

よくある質問(FAQ)

Q読み込んだ日本語が文字化けします。
AFileReaderなど文字コードを指定していないことが原因です。Windowsでは既定がUTF-8でないため、UTF-8ファイルが化けます。StandardCharsets.UTF_8 を明示できる InputStreamReaderFiles 系を使ってください。
Q大きなファイルを読むとメモリ不足になります。
AFiles.readAllLines()readString() は全体をメモリに載せるためです。Files.lines()BufferedReader1行ずつ処理すれば省メモリです。
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に強くなれます。