Java | Java 標準ライブラリ:Files.readAllLines

Java Java
スポンサーリンク

Files.readAllLines を一言でいうと

Files.readAllLines は、

「テキストファイルを“まるごと読み込んで”、1行ずつ List<String> にして返してくれるメソッド」
です。

forBufferedReader を自分で書かなくても、

List<String> lines = Files.readAllLines(path);
Java

の一行で、「そのファイルの全行」がまとめて手に入ります。

小さめのテキストファイルを読むときの、一番手軽な入り口だと思ってください。


基本の使い方と戻り値のイメージ

最もシンプルな例

まずは標準的な使い方から。

import java.nio.file.Files;
import java.nio.file.Path;
import java.io.IOException;
import java.util.List;

public class ReadAllLinesBasic {
    public static void main(String[] args) throws IOException {
        Path path = Path.of("data.txt");

        List<String> lines = Files.readAllLines(path);

        for (String line : lines) {
            System.out.println(line);
        }
    }
}
Java

このコードがやっていることを日本語にすると、

  1. "data.txt" というファイルの場所を Path で表す
  2. Files.readAllLines(path) で、そのファイルを開き、「行ごとに全部読み込む」
  3. 結果を List<String>(行のリスト)として受け取る
  4. for で 1 行ずつ表示する

という流れです。

頭の中では、

  • ファイルの中身
    ["1 行目の文字列", "2 行目の文字列", "3 行目の文字列", ...]

という変換が起きている、とイメージしてください。


文字コード(エンコーディング)をどう扱うか

指定しない場合は「プラットフォームのデフォルト」

Files.readAllLines(path) とだけ書いた場合、
OS のデフォルト文字コードで読み込みます。

Windows 日本語環境なら CP932(いわゆる Shift_JIS っぽいもの)、
Linux ならたいてい UTF-8、などです。

「とりあえず自分の環境で動けばいい」ならこれでも動きますが、
他の環境に持っていくと文字化けの原因になりやすいです。

できれば明示的に文字コードを指定する(UTF-8 推奨)

実務では、基本 UTF-8 を明示しておくほうが安全です。

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.io.IOException;
import java.util.List;

public class ReadAllLinesUtf8 {
    public static void main(String[] args) throws IOException {
        Path path = Path.of("data.txt");

        List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);

        for (String line : lines) {
            System.out.println(line);
        }
    }
}
Java

StandardCharsets.UTF_8 を使うと、「UTF-8 で読む」と明確に宣言できます。

ポイントは、

  • Files.readAllLines(path) だけだと「環境依存」
  • Files.readAllLines(path, UTF_8) なら「どこでも同じ結果」

この差が、のちのち効いてきます。


どんなときに Files.readAllLines を使うべきか

小さめのテキストを「全部メモリに載せてよい」とき

readAllLines は、その名の通り「全行読み込む」ので、
ファイルの全文をメモリに読み込む前提です。

向いているのは、次のような場面です。

  • 数 KB〜数 MB 程度の設定ファイル
  • 小さめの CSV / TSV
  • ログの一部を切り出したテキスト
  • テンプレートファイル(メール本文など)

「ファイル全体を一気に List<String> で持っても問題ないサイズ」なら、
readAllLines はとても書きやすく・読みやすい選択肢です。

向いていないケース(大きすぎるファイル)

数百 MB〜数 GB のログファイルのような巨大ファイルに readAllLines を使うと、
メモリ不足(OutOfMemoryError) を起こす可能性があります。

そのような場合は、

  • 1 行ずつストリームで処理(Files.lines(path)
  • BufferedReader を使った逐次読み出し

など、「必要な分ずつ処理する」スタイルにするべきです。

readAllLines は「全部メモリに載せられる前提の、お手軽メソッド」と覚えておいてください。


具体例:設定ファイルや CSV を読む

例1:設定ファイル(key=value 形式)を読み込んで Map にする

config.txt(UTF-8)に、こんな内容があるとします。

host=localhost
port=8080
mode=dev

これを Map<String, String> にパースする例です。

import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.io.IOException;
import java.util.*;

public class ConfigExample {
    public static void main(String[] args) throws IOException {
        Path path = Path.of("config.txt");

        List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);

        Map<String, String> config = new HashMap<>();

        for (String line : lines) {
            line = line.trim();
            if (line.isEmpty() || line.startsWith("#")) {
                continue; // 空行・コメント行をスキップ
            }
            int idx = line.indexOf('=');
            if (idx == -1) continue; // 不正な行はスキップ

            String key = line.substring(0, idx).trim();
            String value = line.substring(idx + 1).trim();
            config.put(key, value);
        }

        System.out.println("host = " + config.get("host"));
        System.out.println("port = " + config.get("port"));
        System.out.println("mode = " + config.get("mode"));
    }
}
Java

ここでのポイントは、

  • readAllLines で全行を List<String> にする
  • for で 1 行ずつ処理して、値を抽出する

という、非常に自然な流れを作れることです。

例2:簡単な CSV を読み込む

users.csv(UTF-8)に、こんな内容があるとします。

id,name,age
1,Alice,20
2,Bob,25
3,Carol,30

これを行ごとに分解し、カンマで split する例です。

import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.io.IOException;
import java.util.List;

public class CsvExample {
    public static void main(String[] args) throws IOException {
        Path path = Path.of("users.csv");

        List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);

        // 1行目はヘッダとして扱う
        boolean isFirst = true;
        for (String line : lines) {
            if (isFirst) {
                isFirst = false;
                continue;
            }
            String[] cols = line.split(",", -1); // 簡単な例として

            String id   = cols[0];
            String name = cols[1];
            String age  = cols[2];

            System.out.println(id + " " + name + " " + age);
        }
    }
}
Java

本格的には専用の CSV パーサーを使った方がよいですが、
「とりあえずざっくり読みたい」レベルなら、readAllLinessplit で十分なことも多いです。


例外(IOException)とエラー処理の考え方

IOException をどう扱うか

Files.readAllLines は、I/O の失敗(ファイルがない、読めない、など)が起きると
IOException を投げます。

シンプルに書くなら、main に throws を付けてしまう方法もあります。

public static void main(String[] args) throws IOException {
    List<String> lines = Files.readAllLines(Path.of("data.txt"));
    ...
}
Java

もう少し実戦的には、

public static void main(String[] args) {
    try {
        List<String> lines = Files.readAllLines(Path.of("data.txt"));
        // 処理...
    } catch (IOException e) {
        System.err.println("ファイル読み込みに失敗しました: " + e.getMessage());
        e.printStackTrace();
    }
}
Java

のように、try-catch でエラーメッセージを出す形が多いです。

重要なのは、

  • readAllLines が失敗したら、そこで処理を継続させない(lines は正しくない)
  • 原因メッセージ(e.getMessage())をログに残す

という感覚です。


Files.readAllLines を使うときに意識したいこと

一気に List<String> を作るメリット

readAllLines の一番のメリットは、コードが「処理の意図」に集中できることです。

BufferedReader を自分で書くと、どうしても

  • Stream を開く
  • while で 1 行ずつ読む
  • close を忘れないようにする

といった「雑務」が混じってきます。

readAllLines を使うと、
「ファイル内容を List<String> にする」までをライブラリに丸投げできるので、
自分は「各行をどう処理するか」だけ考えればよくなります。

ただし「全部メモリに載る前提」であることを忘れない

繰り返しになりますが、
readAllLines は「全行をメモリに持つ」設計なので、巨大ファイルには不向きです。

  • 「ユーザーがアップロードしてくるファイル」
  • 「運用でどこまで大きくなるか分からないログファイル」

のようなケースでは、
最初から Files.lines(path)BufferedReader でストリーム処理する癖を付けておくのが良いです。


まとめ:Files.readAllLines を自分の中でこう位置づける

Files.readAllLines を初心者向けにまとめると、こうなります。

  • テキストファイルを「全行読み込んで、List<String> にしてくれる」メソッド
  • 文字コードは、第 2 引数に StandardCharsets.UTF_8 などを渡して明示するのがおすすめ
  • 小さめの設定ファイルや CSV を読むのに非常に書きやすい
  • 巨大ファイルには不向き(全部メモリに載る前提だから)
  • Path とセットで使うのが今風(Files.readAllLines(Path.of("..."))

タイトルとURLをコピーしました