【6日でできるJava入門】ファイルの読み込み

 プログラムで大量のデータを扱う場合、ファイルの読み込みは必須のテクニックです。Javaには、テキストファイルを1文字ずつ、または1行ずつ効率よく読み込むための多様なクラスが用意されています。ここでは、代表的なファイル入力方法とその応用について解説します。

1.FileReaderによるファイルの読み込み

1.1. FileReaderクラスの概要

FileReaderクラスは、テキストファイルから文字を1文字ずつ読み込むためのクラスです。主に日本語などマルチバイト文字も正しく扱えます。

機能サンプル記述
ファイルを開くFileReader fr = new FileReader("data.txt");
文字配列で読み込むfr.read(charArray);
ファイルを閉じるfr.close();

1.2. サンプル:ファイル内容を表示するプログラム

ファイル名:sample1.txt
(例:ファイルの内容が「りんご,apple\nばなな,banana\n」のようになっているとする)

※Eclipseの場合、プロジェクト直下に「sample.txt」に配置する。

りんご,apple
ばなな,banana

ファイル名: 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();
    }
}

実行結果

りんご,apple
ばなな,banana

解説

  • read() は実際に読み込んだ文字数を返す。EOF(ファイル末端)になると-1を返す。
  • 読み込んだ分だけStringに変換し、出力する。

2.BufferedReaderで1行ずつ読み込む

2.1. BufferedReaderクラスの特徴

BufferedReaderは、FileReaderなどのReaderクラスと組み合わせて、1行ずつ効率良く読み込むことができます。
readLine()メソッドを使うことで、ファイルを「行単位」で扱えるので、テキストデータの解析が容易です。

主な操作記述例
FileReaderでファイルを開くFileReader fr = new FileReader("sample.txt");
BufferedReaderでラップBufferedReader br = new BufferedReader(fr);
1行ずつ読み込むString line = br.readLine();
ファイルを閉じるbr.close(); fr.close();

2.2. サンプル:ファイルの行数をカウント

ファイル名: 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: りんご,apple
行2: ばなな,banana

解説

  • readLine() はファイルの終端で null を返す。
  • 各行ごとにカウントして、内容をそのまま出力。

3.文字コードと例外処理について

3.1. 文字コードへの配慮

 日本語などマルチバイト文字を確実に扱う場合は、InputStreamReaderBufferedReaderと組み合わせて、文字コードを指定すると安全です。

ファイル名: lesson21_3.java

"UTF-8""Shift_JIS" など、環境に応じて文字コードを指定可能。

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();
    }
}

実行結果

りんご,apple
ばなな,banana

3.2. ファイル操作時の例外

ファイルが見つからない場合や、読み込み時のエラーは例外(Exception)として発生します。
 今回は簡単のため throws Exception でmainメソッドに宣言していますが、実運用ではtry-catch文で例外処理を行うのが一般的です。

3.3 3つのクラスの役割

このプログラムは「テキストファイル(sample.txt)を1行ずつ読み取って表示する」ものです。
 特に FileInputStreamInputStreamReaderBufferedReader という3つの「ストリーム(入出力の流れ)」の連携がポイントです。
それぞれの役割や流れをとあわせて詳しく説明します。

クラス名主な役割何を扱うか本プログラムでの役割
FileInputStreamファイルからバイト単位でデータを読むバイトデータ"sample.txt"の中身を1バイトずつ読み込む
InputStreamReaderバイトデータを文字データに変換する文字(テキスト)バイトをUTF-8でデコードし、「文字」として使えるようにする
BufferedReader文字データを効率よく・行単位で読み込む行単位の文字列1行ずつ読み込めるメソッドreadLine()を提供。バッファで高速化

入力ストリームの流れ(図解)

[ sample.txt(ファイル) ]
      │
      ▼
[ FileInputStream ] ・・・バイト単位で読む
      │
      ▼
[ InputStreamReader (UTF-8) ] ・・・バイト→文字に変換
      │
      ▼
[ BufferedReader ] ・・・文字をまとめて/1行ずつ読む
      │
      ▼
[ プログラム内で1行ずつ処理 ]

3.4 クラスごとの解説

1. FileInputStream

  • 何をする?
    ファイル(ここでは "sample.txt")からデータをバイト単位で読み取るクラス。
  • イメージ:
    「ファイルの生データ」をそのまま1バイトずつ順番に読み込む。
  • 注意:
    そのままでは「日本語」「記号」などの文字データとして使えない(バイト→文字への変換が必要)。

2. InputStreamReader

  • 何をする?
    FileInputStreamなど「バイトストリーム」から受け取ったバイト列を、
    指定した文字コード(ここではUTF-8)で「文字」に変換するクラス。
  • イメージ:
    バイトデータ → "あ" "A" などの文字情報へ変換。
  • 役割:
    「バイトの羅列」を「文字(テキスト)」としてJavaプログラムが読める形にする。

3. BufferedReader

  • 何をする?
    InputStreamReaderなど「文字ストリーム」からデータを受け取り、
    効率よく読み込む(バッファリング)行単位で取り出す(readLineメソッド)
  • イメージ:
    まとめて読み込んで高速化、さらに1行ごとに取り出せる便利さ!
  • 役割:
    1文字ずつでなく「1行まとめて」String型で取得できるので、
    テキストファイルを「1行ずつ」読みたいときに最適。

4.主要なファイル読み込みクラスの比較表

クラス名役割主な特徴
FileReader文字単位でテキストファイルを読むシンプル、漢字も扱える。
BufferedReader1行ずつ効率的にテキストファイルを読むreadLine()で1行単位取得が可能
InputStreamReaderバイト入力を文字入力に変換文字コードの指定ができる。
Scanner様々な区切りでデータ取得(高度な解析も)nextLine(), nextInt()等が使える。

まとめ

  • FileReader はファイルから直接文字を読み込むのに使う。
  • BufferedReader でラップすると「1行ずつ」簡単に読み込める。
  • 日本語ファイルの場合は文字コードにも注意する。
  • ファイルの入出力には例外処理(try-catch)も忘れずに。