
6日でできる 新Java入門|ファイルの読み込み
ファイルの中に眠る修行記録を読み取れるようになると、Javaは一気に実戦向きになる。ファイル読み込みを覚えて、外の世界のデータを自在に扱おう
これまでのJava学習では、プログラムの中に直接書いた値を使って処理を進めることが多かったと思います。けれど、実際のプログラムでは、毎回ソースコードの中に大量のデータを書くわけにはいきません。単語一覧、点数表、設定情報、利用者データ、ログなど、外部のファイルに保存された内容を読み取って使う場面がたくさんあります。そこで大事になるのが ファイルの読み込み です。Javaには、文字を少しずつ読む方法、1行ずつ読み取る方法、文字コードを意識して安全に読む方法など、目的に応じた複数の手段が用意されています。
ドラゴンボールの世界でたとえるなら、修行書庫にたくさんの巻物が保管されていて、必要なときにその巻物を開いて中身を読み取るようなものです。短い修行メモなら少しずつ見てもよいですし、長い修行記録なら1行ずつ読んだ方が分かりやすいこともあります。さらに、古い巻物と新しい巻物では文字の書き方が違うかもしれないので、文字コードを意識して正しく読み解くことも大切になります。
この記事では、FileReader を使った基本的な読み込み、BufferedReader による1行ずつの読み込み、InputStreamReader と FileInputStream を組み合わせた文字コード指定付きの読み込みまで、順番に丁寧に整理していきます。例示するプログラムは Lesson21_1.java、Lesson21_2.java、Lesson21_3.java の3つだけに絞り、それぞれの役割や違いがはっきり分かるように解説していきます。
ファイルの読み込みとは何か
ファイルの読み込みとは、外部に保存されているデータを、Javaプログラムの中へ取り込んで利用することです。プログラムの中だけに値を書いていると、データが増えたときに管理が大変になります。そのため、実用的なプログラムではファイルを読む力がとても重要です。
ファイル読み込みが役立つ場面
| 場面 | 読み込む内容 |
|---|---|
| 単語帳アプリ | 日本語と英語の対応表 |
| 設定ファイル | アプリの初期設定 |
| ログ確認 | 実行結果の履歴 |
| クイズアプリ | 問題文と正解データ |
ドラゴンボール風に言えば、修行場にある巻物から 技名一覧 や 修行記録表 を読み取るような感覚です。
Javaでファイルを読む方法の全体像
Javaでは、ファイルの読み込みに複数のクラスが使えます。どのクラスを使うかによって、文字単位なのか、行単位なのか、文字コードを指定するのかが変わってきます。代表的なものとして、次の4つを押さえておくと整理しやすいです。
主要なファイル読み込みクラス
| クラス名 | 役割 | 主な特徴 |
|---|---|---|
| FileReader | 文字単位でテキストファイルを読む | シンプルで基本を理解しやすい |
| BufferedReader | 1行ずつ効率よく読む | readLine() が使える |
| InputStreamReader | バイト入力を文字入力へ変換 | 文字コードを指定できる |
| Scanner | 区切りごとに読み取る | nextLine() などが使える |
今回は、この中でも FileReader、BufferedReader、InputStreamReader を中心に見ていきます。
FileReaderとは何か
FileReaderクラスは、テキストファイルから文字を読み込むための基本的なクラスです。1文字ずつ読むこともできますし、文字配列へまとめて読み込むこともできます。シンプルなので、ファイル読み込みの入り口としてとても分かりやすいです。
FileReaderの基本操作
| 機能 | サンプル記述 |
|---|---|
| ファイルを開く | FileReader fr = new FileReader("sample1.txt"); |
| 文字配列で読み込む | fr.read(charArray); |
| ファイルを閉じる | fr.close(); |
ドラゴンボール風にたとえるなら、FileReader は巻物を開いて、文字を少しずつ目で追っていく読み方です。
FileReaderでファイル内容を表示する
ここでは、sample1.txt に入っている修行データをそのまま表示する例で見ていきます。元の果物と英単語の組み合わせではなく、技名と技コードの組み合わせに変えています。
ファイル名:sample1.txt
かめはめ波,KAMEHAMEHA
舞空術,BUKUJUTSUファイル名:Lesson21_1.java
import java.io.FileReader;
public class Lesson21_1 {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("sample1.txt");
char[] buffer = new char[128];
while (true) {
int len = fr.read(buffer);
if (len < 0) {
break;
}
System.out.print(new String(buffer, 0, len));
}
fr.close();
}
}実行結果
かめはめ波,KAMEHAMEHA
舞空術,BUKUJUTSUこのプログラムでは、FileReader で sample1.txt を開き、char配列に読み込んでいます。read() の戻り値 len には 実際に読めた文字数 が入り、ファイルの最後まで到達すると -1 が返ります。そこで len < 0 を条件にしてループを終了しています。
Lesson21_1.java の流れ
| 手順 | 内容 |
|---|---|
| 1 | FileReaderでファイルを開く |
| 2 | char配列を用意する |
| 3 | read()で配列へ読み込む |
| 4 | 読み込んだ文字数だけStringへ変換して表示する |
| 5 | 最後にclose()で閉じる |
read() の大事な性質
| 戻り値 | 意味 |
|---|---|
| 0以上 | 読み込んだ文字数 |
| -1 | ファイル終端 |
この戻り値の意味を理解しておくと、ファイル読み込みのループがかなり分かりやすくなります。
BufferedReaderとは何か
BufferedReader は、Reader系クラスを包んで、もっと効率よく読み込むためのクラスです。特に便利なのが readLine() です。これを使うと、ファイルを 1行ずつ 読み取れます。テキストファイルを行単位で扱いたいときは、とても使いやすいです。
BufferedReaderの基本操作
| 主な操作 | 記述例 |
|---|---|
| FileReaderでファイルを開く | FileReader fr = new FileReader("sample1.txt"); |
| BufferedReaderで包む | BufferedReader br = new BufferedReader(fr); |
| 1行ずつ読む | String line = br.readLine(); |
| 閉じる | br.close(); fr.close(); |
ドラゴンボール風に言えば、FileReader が文字を少しずつ追う読み方なら、BufferedReader は 巻物を行ごとに区切って読みやすくした道具 です。
BufferedReaderで行数を数えながら読む
ここでは、修行記録ファイルを1行ずつ読み取り、何行目かも一緒に表示する例にします。
ファイル名:Lesson21_2.java
import java.io.BufferedReader;
import java.io.FileReader;
public class Lesson21_2 {
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("sample1.txt");
BufferedReader br = new BufferedReader(fr);
int count = 0;
String line;
while ((line = br.readLine()) != null) {
count++;
System.out.println("修行記録 " + count + ": " + line);
}
br.close();
fr.close();
}実行結果
修行記録 1: かめはめ波,KAMEHAMEHA
修行記録 2: 舞空術,BUKUJUTSUこのプログラムでは、readLine() を使って1行ずつ読み込んでいます。readLine() はファイルの終わりに到達すると null を返します。そのため、while ((line = br.readLine()) != null) という形で読み進めています。
Lesson21_2.java のポイント
| ポイント | 内容 |
|---|---|
| readLine() | 1行ずつ読み取る |
| 終端判定 | ファイル終端では null が返る |
| count | 何行目かを数える |
| line | 読み込んだ1行分の文字列 |
行ごとにデータを扱うと、CSV風のテキストや設定ファイルを読むときにかなり便利です。
文字コードを意識する必要がある理由
日本語を含むファイルを扱うときは、文字コードを意識することがとても大切です。ファイルが UTF-8 で保存されているのに、別の文字コードとして読んでしまうと、文字化けすることがあります。
ドラゴンボール風にたとえるなら、古い巻物と新しい巻物で使われている文字体系が違うのに、同じ読み方で解読しようとしてしまうようなものです。正しい文字コードを指定することで、はじめて正しく読めます。
InputStreamReader と FileInputStream を組み合わせる意味
文字コードを指定したいときは、FileInputStream、InputStreamReader、BufferedReader を組み合わせる方法がよく使われます。これは少し長く見えますが、それぞれにきちんと役割があります。
3つのクラスの役割
| クラス名 | 主な役割 | 何を扱うか | 本プログラムでの役割 |
|---|---|---|---|
| FileInputStream | ファイルからバイト単位で読む | バイトデータ | ファイルの生データを読む |
| InputStreamReader | バイトを文字に変換する | 文字データ | UTF-8として文字へ変換する |
| BufferedReader | 文字を効率よく1行ずつ読む | 行単位の文字列 | readLine() を使えるようにする |
つまり、3段階になっています。
- ファイルを 生のバイト列 で読む
- そのバイト列を 文字コード付きで文字へ変換する
- 読みやすく 1行ずつ 扱えるようにする
文字コードを指定して読む例
ここでは UTF-8 を明示して、修行記録ファイルを安全に読む例を見ていきます。
ファイル名:Lesson21_3.java
import java.io.*;
public class Lesson21_3 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("sample1.txt"), "UTF-8")
);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
}実行結果
かめはめ波,KAMEHAMEHA
舞空術,BUKUJUTSUこのプログラムでは、FileInputStream でファイルをバイトとして開き、そのバイトを InputStreamReader が UTF-8 として文字へ変換し、最後に BufferedReader が1行ずつ読み取れる形にしています。
入力ストリームの流れ
この3つのクラスの連携を流れで見ると、とても分かりやすいです。
入力ストリームの流れ
| 段階 | 役割 |
|---|---|
| sample1.txt | 元のファイル |
| FileInputStream | バイトとして読む |
| InputStreamReader | バイトを文字へ変換する |
| BufferedReader | 文字列を1行ずつ取り出す |
| プログラム | 読み込んだ行を処理する |
ドラゴンボール風にたとえるなら、巻物を取り出し、生の文字を解読し、読みやすく行ごとに整理して、ようやく修行内容として使えるようになる流れです。
ファイル読み込みで例外処理が必要な理由
ファイル操作では、いろいろな問題が起こる可能性があります。たとえば、ファイルが存在しない、読み込み中に失敗する、文字コードが合わない、といったことです。そのため、例外処理を考える必要があります。今回の例では簡単にするため、mainメソッドに throws Exception を付けています。
主なトラブル例
| 状況 | 起こりうる問題 |
|---|---|
| ファイルが存在しない | 開けない |
| 読み込み中に問題が起きる | 途中で失敗する |
| 文字コードが違う | 文字化けする |
実運用では try-catch を使うことが多いですが、入門ではまず 例外が起こる可能性がある ことを知っておくのが大切です。
FileReader と BufferedReader と InputStreamReader の違いを整理する
ここまで学んだ3つの読み方を比べると、それぞれの得意分野が見えてきます。
3つの方法の比較
| 方法 | 向いている場面 | 特徴 |
|---|---|---|
| FileReader | 基本的な文字読み込み | シンプルで理解しやすい |
| BufferedReader | 行単位で読みたいとき | readLine() が便利 |
| InputStreamReader + BufferedReader | 文字コードを明示したいとき | 日本語を安全に扱いやすい |
この違いを知っておくと、目的に応じてどの方法を使えばよいか判断しやすくなります。
ファイル読み込みの流れを図で整理
ファイル読み込みは、ファイルを開いて、その中の文字をプログラムへ取り込み、必要な単位で扱う流れです。
下図は、sample1.txt のようなファイルからデータが読み込まれ、FileReader または FileInputStream → InputStreamReader → BufferedReader を通って、最終的にプログラムの中で1行ずつ処理される流れを示しています。どのクラスがどの段階を担当しているかが分かる構成です。
↓クリックすると拡大表示されます。

この図が示していること
この図は、ファイルの内容がそのまま使われるのではなく、読み込み用クラスを通して少しずつプログラムへ渡されていることを示しています。とくに、文字単位、バイト単位、行単位という違いが見える構成です。
この図から分かること
この図を見ると、ファイル読み込みには役割の違うクラスが順番に協力していることが分かります。どのクラスを使うかで、読み取り方や安全性が変わることも理解しやすくなります。
3つのクラスの役割を図で整理する
InputStreamReader を使う読み方は少し長く見えるので、3つのクラスの役割を図で整理すると理解しやすいです。
下図は、ファイルからバイトを読む FileInputStream、そのバイトを文字へ変換する InputStreamReader、そして行単位で扱いやすくする BufferedReader の3段階を縦方向または横方向に並べて示したものです。1つひとつのクラスが違う役割を持って連携していることが見える図です。
↓クリックすると拡大表示されます。

この図が示していること
この図は、FileInputStream、InputStreamReader、BufferedReader が、それぞれ別の役割を持ちながら連携してファイルを読んでいることを示しています。1つのクラスだけで全部をしているわけではないことが見えます。
この図から分かること
この図を見ると、ファイル読み込みは 生データを取る、文字へ変える、行として扱う という段階的な流れでできていることが分かります。3つのクラスの役割の違いが分かります。
ファイル読み込みを理解すると、プログラムが外部データを扱えるようになる
Javaでファイルを読み込めるようになると、プログラムはソースコードの中だけに閉じた存在ではなくなります。外部のテキストデータを取り込み、その内容を使って処理を進められるようになるからです。大量のデータを扱うとき、ファイル読み込みは欠かせない技術です。
ドラゴンボールの世界でも、修行のたびに新しい巻物を開き、その内容を読んで次の課題を決めていくなら、巻物を正しく読める力が必要です。Javaのファイル読み込みもそれと同じで、外の世界にある情報を、正しく、効率よく、自分のプログラムへ取り込むための大切な力です。
