Javaでファイルを読み込む方法は、目的で決まります。
小さなファイルはFiles.readString()で一括、1行ずつ処理するならBufferedReaderかFiles.lines()、CSVはsplit()か専用ライブラリです。
値にカンマを含むCSV・数GB級のログ・resourcesフォルダの設定ファイルなど、つまずきやすいケースもコピペで動くサンプルコードで示します。
この記事でわかること
- File・BufferedReader・Scannerを使ったファイル読み込みの基本3方法
- BufferedReader・Scanner・Filesクラスの違いと使い分け
- CSVをListに格納する方法(ヘッダー・空欄・文字コード対策)とOpenCSV・Apache Commons CSVの使い方
- 大容量ファイル・resourcesフォルダ・プロパティファイル・JSONの読み込みサンプル
- FileNotFoundException・IOExceptionへの対処とtry-with-resourcesの安全な書き方
PARTS LIST /目次
Javaファイル読み込みの基本3つの方法
Javaのファイル読み込みとは、テキストファイルやCSV・プロパティファイルなどの中身を、プログラムから扱える形に変換する処理のことです。
具体的には、BufferedReaderやFilesクラスといった標準APIのクラスを経由します。
Javaのファイル読み込みは、複数のクラスを組み合わせて使います。まずは基本のFile・BufferedReader・Scannerの3つを押さえましょう。
Fileクラスを使った基本的な扱い方
まず基本となるのがjava.io.Fileクラスです。注意点として、Fileクラス自体にファイルを読み込む機能はありません。
Fileクラスは、ファイルやディレクトリのパスを抽象的に表現するためのものです。
ファイルが存在するかどうかを確認したり、ファイル名を取得したりする際に使います。ファイル操作の「窓口」と考えるとわかりやすいでしょう。
import java.io.File;
public class FileExample {
public static void main(String[] args) {
// ファイルのパスを指定してFileオブジェクトを作成
File file = new File("sample.txt");
// ファイルの存在確認
if (file.exists()) {
System.out.println("ファイルは存在します。");
// ファイルの絶対パスを取得
System.out.println("パス: " + file.getAbsolutePath());
// ファイル名を取得
System.out.println("ファイル名: " + file.getName());
} else {
System.out.println("ファイルが見つかりません。");
}
}
}
このコードは、sample.txtというファイルが存在するかどうかをチェックするだけです。
実際の読み込みは、このFileオブジェクトを他のクラス(BufferedReaderなど)と組み合わせて行います。
BufferedReaderで1行ずつ読み込む
テキストファイルを1行ずつ読み込んで処理したい場合に最もよく使われるのがBufferedReaderクラスです。
BufferedReaderは、文字をバッファリングしながら読み込むため、効率的に処理できます。
readLine()メソッドを使うと、1行ずつ文字列として簡単に取得できるのが大きな特徴です。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderExample {
public static void main(String[] args) {
File file = new File("sample.txt");
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
// 1行ずつ読み込み、行がなくなるまでループ
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
この例ではFileReaderと組み合わせています。
FileReaderがファイルから文字を読み込み、それをBufferedReaderが効率化して1行ずつ提供するイメージです。
私自身、業務で数十万行のアクセスログを解析するバッチ処理を書いた際に、BufferedReaderの安定性に助けられました。
メモリ消費が一定のまま処理が進むので、本番環境でも安心して使えます。
Scannerを使った簡単な入力処理
Scannerクラスは、コンソールからの入力受付によく使われますが、ファイルの読み込みにも利用できます。
Scannerの便利な点は、スペースや改行などの区切り文字を指定して、単語ごとにデータを読み込めることです。
nextInt()やnextDouble()を使えば数値を直接読み取れるため、型変換の手間も省けます。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
File file = new File("sample.txt");
try (Scanner scanner = new Scanner(file)) {
// ファイルの最後まで単語ごとに読み込む
while (scanner.hasNext()) {
String word = scanner.next();
System.out.println(word);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
簡単なテキストデータや、スペース区切りのデータを手軽に扱いたい場合にはScannerが便利です。
ファイル読み込み方法の比較と使い分け
どの方法を使うかは、次の順に質問に答えていけば決まります。
getResourceAsStream()Fileクラスでは読めないクラスパス上のファイルも、JARに入れた後まで動作する。見つからないとnullを返すBufferedReader + split(",", -1)第2引数に-1を渡すと、行末の空欄も空文字として残るBufferedReader.readLine()1行ずつ文字列として取得できる定番の方法Files.readString()Java 11以降、1行で全内容を文字列にできる。大きなファイルには不向きBufferedReaderとScannerの違い
BufferedReaderとScannerはどちらもよく使われるため、どちらを選ぶべきか迷うかもしれません。主な違いはパフォーマンスと機能性です。
テキストファイルを1行ずつ読むだけならBufferedReaderを選びます。
スペース区切りのデータや数値を直接扱いたいときはScannerが向いています。
Filesクラス(Java 7以降)の活用
Java 7で導入されたNIO.2(New I/O 2)のFilesクラスを使うと、ファイル読み込みをさらに簡潔に記述できます。
2026年現在の最新LTSはJava 25(2025年9月リリース)です。
Java 21も含め幅広いLTSバージョンで引き続き推奨されるAPIのため、これから学ぶならこの方法を最優先で覚えましょう。
これまでのBufferedReaderなどを使った書き方よりも、はるかに少ないコード量で済むのが最大のメリットです。
例えば、ファイルの内容をすべて一度に読み込んで文字列にする場合、Files.readString()を使えばたった1行です。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class FilesExample {
public static void main(String[] args) {
Path path = Paths.get("sample.txt");
try {
// ファイルの全行をリストとして読み込む (Java 8+)
// List<String> lines = Files.readAllLines(path);
// System.out.println(lines);
// ファイルの全内容を1つの文字列として読み込む (Java 11+)
String content = Files.readString(path);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
小さな設定ファイルなどを読み込む際には、このFilesクラスを使う方法が最も手軽で間違いがありません。
ただし、巨大なファイルを一括で読み込むとメモリを大量に消費するため、注意が必要です。
文字コード(エンコーディング)への注意点
Windowsで作成したテキストファイルをMacやLinuxで開くと、文字化けすることがあります。
Javaのファイル読み込みでも、文字コードの指定を誤ると同じ文字化けが起きます。
Java 17以前では、特に指定しない場合、OSのデフォルト文字コードが使われていました。
しかしJava 18以降、デフォルト文字コードはOSに関係なくUTF-8に統一されています。
Java 17以前の環境やShift_JISファイルを扱う場合は、明示的に文字コードを指定する必要があります。
私の経験では、文字コード問題は「開発環境では正常に動くが本番で文字化けする」という形で発覚するケースが大半です。
開発端末がMac(UTF-8)で本番がWindows Server(Shift_JIS)だった場合に頻発します。
読み込むファイルの文字コードが分かっている場合は、必ず明示的に指定しましょう。
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
public class CharsetExample {
public static void main(String[] args) {
// Shift_JISでエンコードされたファイルを読み込む例(MS932を指定)
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("sample_sjis.txt"), Charset.forName("MS932")))) { // ここでMS932(Shift_JIS系)を指定
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
InputStreamReaderを使うと、FileInputStreamで読み込んだバイトデータを、指定した文字コードで文字に変換できます。
2026年現在、新規プロジェクトではUTF-8が事実上の標準です。
ただし、官公庁系システムや銀行系レガシーではShift_JISが残っていることもあるため、この方法は覚えておくと役立ちます。
実践的なファイル読み込みサンプルコード
テキストファイルを一括で読み込む
設定ファイルなど、数KB程度の小さなファイルであれば、中身を一度にすべてメモリに読み込んでしまうのが最も簡単です。
前述のFiles.readString()が最適です。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class ReadAllText {
public static void main(String[] args) {
Path path = Path.of("config.txt");
try {
String configContent = Files.readString(path);
System.out.println("--- 設定ファイルの内容 ---");
System.out.println(configContent);
} catch (IOException e) {
System.err.println("ファイルの読み込みに失敗しました: " + e.getMessage());
}
}
}
この方法なら、面倒なループ処理やリソースのクローズ処理を気にする必要がありません。
CSVファイルを読み込んで処理する|split()とOpenCSVの使い分け
カンマ区切りのCSVファイルは、データ交換のフォーマットとして頻繁に使われます。
BufferedReaderで1行ずつ読み込み、Stringクラスのsplit()メソッドでカンマを基準に分割するのが基本的な処理方法です。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CsvReader {
public static void main(String[] args) {
String csvFile = "users.csv";
String line;
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
// ヘッダー行を読み飛ばす場合
// br.readLine();
while ((line = br.readLine()) != null) {
String[] user = line.split(",");
System.out.println("ID: " + user[0] + ", 名前: " + user[1] + ", メール: " + user[2]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
users.csvファイルを1行ずつ読み込み、各行をカンマで分割してユーザー情報を表示します。
値にカンマを含まない単純なCSVなら、この方法で十分です。
ただし実務のCSVは、顧客名や住所の欄にカンマ・ダブルクォート・改行が入っていることがよくあります。
判断の基準は行数ではなく中身です。値にカンマ・ダブルクォート・改行が入る可能性があるなら、最初からOpenCSVやApache Commons CSVを使いましょう。
あとからカンマ混入のバグを直すより、結果的に手間が少なく済みます。
CSVをListに格納する|ヘッダー・空欄・文字コード対策
読み込んだCSVは、あとで集計や並べ替えをするためにList<String[]>へ格納するのが定番です。
次のコードは、実務でつまずきやすい3点(ヘッダー行・末尾の空欄・文字コード)をまとめて対策しています。
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
public class CsvToList {
public static void main(String[] args) throws IOException {
Path path = Path.of("users.csv");
List<String[]> rows = new ArrayList<>();
// 文字コードを明示する(ExcelのCSVなら Charset.forName("MS932"))
try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
String header = br.readLine(); // 1行目(ヘッダー)を読み飛ばす
String line;
while ((line = br.readLine()) != null) {
if (line.isBlank()) {
continue; // 空行はスキップ
}
// 第2引数に-1を渡すと、末尾の空欄も要素として残る
rows.add(line.split(",", -1));
}
}
System.out.println("データ件数: " + rows.size());
for (String[] row : rows) {
System.out.println("ID: " + row[0] + ", 名前: " + row[1] + ", メール: " + row[2]);
}
}
}
split(",")は、行末の空欄を配列から消してしまいます。
メール欄が空の行でrow[2]にアクセスすると、ArrayIndexOutOfBoundsExceptionで止まります。第2引数に-1を渡せば、空欄も空文字として残ります。
String line = "1,山田,";
System.out.println(line.split(",").length); // 2(末尾の空欄が消える)
System.out.println(line.split(",", -1).length); // 3(空欄も残る)
ExcelでCSV保存したファイルは、文字コードがShift_JIS(WindowsではMS932)のことが多いです。
その場合はStandardCharsets.UTF_8をCharset.forName("MS932")に変えてください(java.nio.charset.Charsetのimportが必要です)。
「CSV UTF-8」形式で保存したファイルは先頭にBOMが付くため、1列目のヘッダー名に見えない文字が混ざる点にも注意しましょう。
OpenCSV・Apache Commons CSVでCSVを読み込む
OpenCSVは、引用符付きフィールド内のカンマや改行を正しく解釈できる専用ライブラリです。
Maven/Gradleに依存関係を追加するだけで使えます。
<!-- pom.xml -->
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.12.0</version>
</dependency>
import com.opencsv.CSVReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
public class CsvReaderOpenCSV {
public static void main(String[] args) throws IOException {
String path = "users.csv";
try (CSVReader reader = new CSVReader(new FileReader(path))) {
List<String[]> lines = reader.readAll();
for (String[] line : lines) {
System.out.println("ID: " + line[0] + ", 名前: " + line[1] + ", メール: " + line[2]);
}
} catch (com.opencsv.exceptions.CsvException e) {
e.printStackTrace();
}
}
}
reader.readAll()を使えば、カンマや改行が値の中に含まれていても正しく行単位・列単位に分割してくれます。
自前のsplit(",")は手軽な反面、値の中にカンマが1つでも混入すると壊れます。
もう1つの定番がApache Commons CSVです。RFC 4180(CSVの標準仕様)に沿って解析し、ヘッダーの列名で値を取り出せるのが強みです。
<!-- pom.xml -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.14.1</version>
</dependency>
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class CsvReaderCommons {
public static void main(String[] args) throws IOException {
// 1行目をヘッダーとして扱い、列名で値を取り出せるようにする
CSVFormat format = CSVFormat.DEFAULT.builder()
.setHeader()
.setSkipHeaderRecord(true)
.get();
try (Reader reader = Files.newBufferedReader(Path.of("users.csv"), StandardCharsets.UTF_8);
CSVParser parser = format.parse(reader)) {
for (CSVRecord record : parser) {
System.out.println(record.get("id") + " / " + record.get("name"));
}
}
}
}
record.get("name")のように列名で書けるため、列の順番が変わっても修正が要りません。
列番号で素早く書きたいならOpenCSV、列名で読みやすく書きたいならCommons CSV、と選ぶと迷いません。
大容量ファイルを効率的に扱う
数GBにもなるような大容量のログファイルなどを扱う場合、ファイル全体をメモリに読み込むのは現実的ではありません。
ヒープ領域が足りなくなり、OutOfMemoryErrorでプログラムが停止します。
「まとめて読み込んだ方が効率的なはず」という直感は、データ量が増えるほど裏切られます。
以前、Spring Batchのバッチ処理でchunk sizeを1000件に設定していました。
その結果、本番環境がOutOfMemoryErrorで落ちたことがあります。
原因調査に2時間かかった一方、修正はchunk sizeを100件に下げるだけの5分で完了しました。ファイル読み込みでも構造は同じです。
Files.readAllLines()で「とりあえず全部読む」実装は、開発環境の小さなテストデータでは問題が表面化しません。
本番の大容量ファイルで、初めて牙を剥きます。
このようなケースでは、ストリーム処理が必須です。ストリーム処理とは、データを少しずつ読み込みながら処理を進める方式です。
BufferedReaderのreadLine()ループや、Java 8から導入されたFiles.lines()メソッドがこれにあたります。
Files.readAllLines() / readString()Files.lines() / BufferedReaderOutOfMemoryError で停止2026年現在の最新LTSであるJava 25でも変わらず推奨される書き方です。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
public class LargeFileReader {
public static void main(String[] args) {
Path path = Path.of("large_log_file.log");
// try-with-resourcesでStreamを自動的にクローズする
try (Stream<String> lines = Files.lines(path)) {
// "ERROR"という単語を含む行だけをカウントする
long errorCount = lines.filter(line -> line.contains("ERROR")).count();
System.out.println("エラー行数: " + errorCount);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Files.lines()は、ファイルを行ストリームとして扱えるようにします。
メモリ消費を最小限に抑えながら、フィルタリングや集計といった高度なデータ処理を簡潔に書けます。
resourcesフォルダのファイル読み込み(クラスパス)
MavenやGradleのプロジェクトでは、設定ファイルやテンプレートをsrc/main/resourcesに配置するのが一般的です。
JARにまとめた後は、resourcesフォルダ内のファイルをFileクラスのパスで指定しても読み込めません(IDEから実行する場合はたまたま動くこともあります)。
代わりにgetResourceAsStream()を使います。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
public class ResourceReader {
public static void main(String[] args) {
// クラスパス上の "config.properties" を読み込む
try (InputStream is = ResourceReader.class.getResourceAsStream("/config.properties");
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException | NullPointerException e) {
System.err.println("リソースの読み込みに失敗しました: " + e.getMessage());
}
}
}
パスの先頭に/を付けるとクラスパスのルートからの絶対パスになります。/なしだと呼び出し元クラスのパッケージからの相対パスです。
getResourceAsStream()は見つからない場合にnullを返すため、NullPointerExceptionへの対策も忘れずに入れておきましょう。
そのため、プロジェクト内の設定ファイルやテンプレートにはgetResourceAsStream()を使うのが鉄則です。
プロパティファイルを読み込む(Propertiesクラス)
設定値をキーとバリューのペアで管理したい場合は、java.util.Propertiesクラスが便利です。
.properties形式のファイルをload()メソッドに渡すだけで、シンプルな設定管理が実現できます。
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesExample {
public static void main(String[] args) {
Properties props = new Properties();
// クラスパス上の config.properties を読み込む
try (InputStream is = PropertiesExample.class.getResourceAsStream("/config.properties")) {
props.load(is);
String dbUrl = props.getProperty("db.url");
System.out.println("db.url = " + dbUrl);
} catch (IOException e) {
System.err.println("プロパティファイルの読み込みに失敗しました: " + e.getMessage());
}
}
}
前述のgetResourceAsStream()と組み合わせれば、JARファイルにパッケージされた設定ファイルもそのまま読み込めます。
DB接続情報やAPIキーなど、環境ごとに差し替えたい値を管理する用途でよく使われる方法です。
ここで注意したいのが文字コードです。
Properties#load(InputStream)は、内部でISO-8859-1(Latin-1)としてバイト列を解釈します。
そのため、日本語のコメントや値を含む.propertiesファイルを上記のコードでそのまま読み込むと文字化けします。
日本語を扱う場合は、load(InputStream)ではなくload(Reader)を使います。
Readerには、UTF-8を指定したInputStreamReaderを渡してください。
JSONファイルを読み込む
JavaにはJSONを解析する標準APIが含まれていないため、JacksonやGsonといった外部ライブラリを使うのが一般的です。
ここでは広く使われているJacksonの例を紹介します。
2025年10月には、groupIdがtools.jackson.coreに変わるJackson 3.0もGAリリースされました。
ただし既存プロジェクトの多くはまだ2.x系のため、ここでは安定した2.x系の書き方を使います。
// build.gradle: implementation 'com.fasterxml.jackson.core:jackson-databind:2.22.2'
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.IOException;
public class JsonExample {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
try {
User user = mapper.readValue(new File("user.json"), User.class);
System.out.println(user.getName());
} catch (IOException e) {
System.err.println("JSONの読み込みに失敗しました: " + e.getMessage());
}
}
}
readValue()にJSONファイルとマッピング先のクラスを渡すだけで、フィールド名が一致していれば自動的にオブジェクトへ変換してくれます。
Files.readString()で文字列として読み込んでから自前でパースすることも、技術的には可能です。
ただし、ネストしたJSONの扱いが煩雑になるため、実務ではライブラリを使う方法が推奨されます。
ファイル読み込み時のエラー処理
ファイル操作にはエラーがつきものです。ファイルが存在しなかったり、読み込み権限がなかったりと、予期せぬ事態は常に起こり得ます。
FileNotFoundExceptionへの対応
FileNotFoundExceptionは、その名の通り「指定されたパスにファイルが見つからない」場合に発生する、最も代表的な例外です。
FileNotFoundExceptionが発生するということは、プログラムの前提が崩れている状態です。
ユーザーにファイルパスを再入力させたり、処理を中断してエラーメッセージを表示したりといった対応が必要です。
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FileNotFoundHandler {
public static void main(String[] args) {
File file = new File("non_existent_file.txt");
try {
Scanner scanner = new Scanner(file);
// ... 読み込み処理 ...
} catch (FileNotFoundException e) {
System.err.println("エラー: ファイルが見つかりません。");
System.err.println("パスを確認してください: " + file.getAbsolutePath());
}
}
}
IOExceptionの基本的なハンドリング
IOExceptionは、I/O操作全般で発生する可能性のある、より広範な例外です。
FileNotFoundExceptionもIOExceptionの一種です。
ディスクの故障やネットワークの切断で読み込みが中断された場合にもIOExceptionが発生します。
ファイル操作を行うコードは、必ずIOExceptionを処理するtry-catchブロックで囲んでください。
try-with-resourcesを使った安全な書き方
Java 7から導入されたtry-with-resources文は、ファイルを閉じる処理を自動化し、エラー処理のコードを大幅に短くしました。
古いコードでは、finallyブロックでclose()メソッドを呼び出し、リソースを明示的に閉じる必要がありました。
このclose()処理を忘れると、ファイルハンドルが解放されずに残り、システムの不安定化を招く原因となります。
try-with-resourcesを使えば、tryブロックを抜ける際に自動的にリソースをクローズしてくれます。
// 悪い例(Java 6以前の古い書き方)
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("sample.txt"));
// ... 読み込み処理 ...
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close(); // 手動でクローズする必要がある
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 良い例(Java 7以降のモダンな書き方)
try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
// ... 読み込み処理 ...
// tryブロックを抜ける際に自動でbr.close()が呼ばれる
} catch (IOException e) {
e.printStackTrace();
}
コードがシンプルになるだけでなく、close()の呼び忘れも防げるため、現在のJavaではtry-with-resources文を使うのが常識です。
特別な理由がない限り、必ずこの書き方を採用してください。
実際のコードレビューでも、try-with-resourcesを使っていないコードは即座に指摘対象になります。
レガシーコードのリファクタリング案件でも、最初に手をつけるべき改善箇所です。
よくある質問(FAQ)
Q1. Javaでファイルを読み込む最も簡単な方法は?
A1. Java 11以降であればFiles.readString(Path)が最も簡単です。1行で全内容を文字列として取得できます。ただし、ファイルサイズが大きい場合はメモリを圧迫するため、数KB〜数MB程度の設定ファイルや小さなテキストファイル向けです。
Q2. BufferedReaderとScannerはどちらを使うべき?
A2. テキストファイルを1行ずつ処理するならBufferedReaderが高速で推奨です。スペース区切りのデータや数値を直接読み取りたい場合はScannerが便利です。パフォーマンスが重要な大規模処理ではBufferedReaderかFiles.lines()が向いています。
Q3. 大容量ファイルを読み込むとOutOfMemoryErrorが出るのはなぜ?
A3. Files.readAllLines()やFiles.readString()は、ファイル全体をメモリに展開します。そのため、数GB規模のファイルではヒープ領域が不足します。Files.lines()やBufferedReaderのループで1行ずつ処理するストリーム方式に切り替えてください。
Q4. resourcesフォルダ内のファイルを読み込むにはどうすればいい?
A4. JARにまとめた後は、Fileクラスでパスを指定しても読み込めません。getResourceAsStream()を使い、クラスパス経由でInputStreamとして取得してください。JARファイルにパッケージした後も同じ方法で読み込めます。
Q5. プロパティファイルの日本語が文字化けするのはなぜ?
A5. Properties#load(InputStream)が内部でISO-8859-1(Latin-1)としてバイト列を解釈するためです。日本語を含む場合はload(Reader)にUTF-8指定のInputStreamReaderを渡してください。
Q6. JSONファイルを読み込むのに標準APIだけで足りる?
A6. いいえ、足りません。JavaにはJSON解析の標準APIが含まれていないため、JacksonやGsonなどの外部ライブラリを使うのが一般的です。Files.readString()で読み込んで自前パースすることも技術的には可能ですが、ネストしたJSONでは煩雑になります。
Q7. 文字コードを指定せずにファイルを読み込むとどうなる?
A7. Java 18以降は、OSに関係なくUTF-8として読み込まれます。Shift_JISのファイルは文字化けするため、文字コードを明示してください。
Java 17以前はOSの既定の文字コードが使われるため、Windows(MS932)ではUTF-8のファイルが文字化けします。どのバージョンでもStandardCharsetsで指定しておくのが確実です。
Q8. CSVを読み込んで配列やListに格納するには?
A8. BufferedReaderで1行ずつ読み、line.split(",", -1)で分割した配列をList<String[]>に追加します。第2引数の-1を付けないと、行末の空欄が消えて列数がずれます。値にカンマや改行が入る場合はOpenCSVかApache Commons CSVを使ってください。
Q9. ファイルの途中の行から・指定した行だけ読み込むには?
A9. Files.lines()のskip()とlimit()を組み合わせます。先頭から順に読み飛ばす方式ですが、1行ずつ処理するため大きなファイルでもメモリを圧迫しません。
// 11行目から5行分だけ読む(先頭10行を飛ばす)
try (Stream<String> lines = Files.lines(Path.of("app.log"))) {
lines.skip(10).limit(5).forEach(System.out::println);
}
まとめ
迷ったら「ファイルの大きさ」と「1行ずつ処理するか」の2点で選べば、ほとんどのケースに対応できます。
目的別に使い分ける読み込み方法
- 小さなファイルを一括で読みたい ->
Files.readString()やFiles.readAllLines()が手軽で最適。 - ファイルを1行ずつ処理したい ->
BufferedReaderを使うのが基本。パフォーマンスも良い。 - CSVを読んでListに格納したい -> 単純なCSVは
split(",", -1)、値にカンマや改行が入るなら OpenCSV か Apache Commons CSV。 - 大容量ファイルを効率的に扱いたい ->
Files.lines()を使ったストリーム処理が向いている。メモリを圧迫しない。 - スペース区切りなど簡単なデータを解析したい ->
Scannerが便利。 - クラスパス上のリソースを読みたい ->
getResourceAsStream()を使えばJAR内でも動作する。
| REV. | DATE | 内容 |
|---|---|---|
| 6 | 2026-10-15 | 図解を描き直し(図面のデザインにそろえた) |
| 5 | 2026-10-04 | 記載内容の事実確認と修正 |
| 4 | 2026-09-01 | 2026年9月時点の情報で全体を見直し(古い記述を2件更新) |
| 3 | 2026-08-17 | 2026年8月時点の情報で全体を見直し(古い記述を3件更新) |
| … ほか1回の改訂 | ||
| 1 | 2025-10-04 | 初版 |









