Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaでEOFExceptionが発生する原因と対処法を実例コードで解説

Javaでファイルを読み込む際、ファイルの終端(EOF:End Of File)に到達すると、EOFException がスローされることがあります。特に、DataInputStream のような入力ストリームオブジェクトを使ってデータを読み込む場合に発生しやすい例外です。一方、他のストリームクラスでは、ファイルの終端に達したときに特定の戻り値(例えば -1)が返される仕組みになっています。

EOFExceptionとは何か

EOFExceptionjava.io パッケージに属するチェック例外で、データ入力の途中で予期せずストリームの終端に達したことを示します。代表的な例が DataInputStream クラスです。このクラスは readBoolean()readByte()readChar() などのメソッドを提供し、プリミティブ型の値を読み込むことができますが、これらのメソッドで読み込み中にファイルの終端に達すると EOFException がスローされます。

EOFExceptionが発生するコード例

次の例では、DataInputStreamreadChar() メソッドを使ってファイルから文字を読み込んでいます。無限ループの中で読み込み続けるため、ファイルの終端に達した時点で例外が発生します。

import java.io.DataInputStream;
import java.io.FileInputStream;

public class EOFExample {
    public static void main(String[] args) throws Exception {
        // readChar()メソッドでファイルを読み込む
        DataInputStream dis = new DataInputStream(new FileInputStream("D:\\data.txt"));
        while (true) {
            char ch;
            ch = dis.readChar();
            System.out.print(ch);
        }
    }
}

実行時の例外出力

Hello how are youException in thread "main" java.io.EOFException
   at java.io.DataInputStream.readChar(Unknown Source)
   at SEPTEMBER.remaining.EOFExample.main(EOFExample.java:11)

このように、ファイルの内容が出力された直後に EOFException がスローされ、プログラムが異常終了してしまいます。

EOFExceptionへの対処法1:別のストリームクラスを使う

DataInputStream クラスでは、ファイルの終端に到達せずに読み込みを完了することはできません。そのため、終端判定が必要な場合は、InputStream インターフェースの他のサブクラス(例えば FileInputStream)を使用するのが有効です。FileInputStreamread() メソッドは、ファイルの終端に達すると -1 を返すため、例外に頼らず自然な形でループを終了できます。

FileInputStreamを使った書き換え例

次の例では、先ほどのプログラムを DataInputStream の代わりに FileInputStream を使う形に書き換えています。

import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class AIOBSample {
    public static void main(String[] args) throws Exception {
        // 書き込むデータを用意
        byte[] buf = " Hello how are you".getBytes();
        // DataOutputStreamでファイルに書き込む
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\data.txt"));
        for (byte b : buf) {
            dos.writeChar(b);
        }
        dos.flush();
        System.out.println("Data written successfully");
    }
}

出力結果

Data written successfully

EOFExceptionへの対処法2:try-catchで捕捉する

もう一つの一般的な対処法は、try-catch ブロックで EOFException を明示的に捕捉し、ファイルの終端に達したことを正常な終了条件として扱う方法です。これにより、例外を「エラー」ではなく「読み込み完了の合図」として活用できます。

import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;

public class HandlingEOF {
    public static void main(String[] args) throws Exception {
        DataInputStream dis = new DataInputStream(new FileInputStream("D:\\data.txt"));
        while (true) {
            char ch;
            try {
                ch = dis.readChar();
                System.out.print(ch);
            } catch (EOFException e) {
                // ファイルの終端に達したら正常にループを抜ける
                System.out.println("");
                System.out.println("End of file reached");
                break;
            } catch (IOException e) {
                // その他のI/O例外に対応
            }
        }
    }
}

出力結果

Hello how are you
End of file reached

まとめ

EOFException は、DataInputStream などでプリミティブ型のデータを読み込む際にファイルの終端へ到達することでスローされる例外です。対処法としては、次の2つが代表的です。

  • 別のストリームクラスを使う: FileInputStream など、終端で -1 を返すクラスに置き換えることで、例外を回避できる。
  • try-catchで捕捉する: EOFException を捕捉し、ファイルの終端到達を正常な終了条件として処理する。

用途に応じて適切な方法を選択することで、安全かつ効率的にファイル読み込み処理を実装できます。

  1. Javaでディレクトリ階層を作成する方法|mkdirs()メソッドの使い方を解説

    java.ioパッケージに含まれるFileクラスは、システム上のファイルやディレクトリ(パス名)を表現するためのクラスです。このクラスには、ファイルやディレクトリに対してさまざまな操作を行うためのメソッドが数多く用意されています。 mkdir()メソッドを使用すると、現在のFileオブジェクトが表すパスにディレクトリを1つ作成できます。ただし、このメソッドは親ディレクトリが存在しない場合には失敗するという点に注意が必要です。 ディレクトリ階層を作成するには? 複数階層からなる新しいディレクトリ構造を一括で作成したい場合は、同じFileクラスのmkdirs()メソッドを使用します。このメソッドは

  2. 【Java】JSONオブジェクトをファイルに書き込む方法(json-simpleライブラリの使い方)

    JSON(JavaScript Object Notation)は、現在もっとも広く使われているデータ交換フォーマットのひとつです。軽量であることと、特定のプログラミング言語に依存しないことが大きな特徴で、異なるシステム間でのデータやり取りに最適です。 JavaでJSONファイルを読み書きするには、json-simple ライブラリが便利です。json-simpleは軽量なJSON処理ライブラリで、JSONテキストのエンコード(書き込み)とデコード(読み込み)の両方に対応しており、JSON仕様(RFC4627)に完全準拠しています。 ライブラリの準備 json-simpleを使用するには、まず