Java で EOFException を処理する

Mohd Mohtashim Nawaz 2023年10月12日
  1. JavaIOException のサブクラスとしての JavaEOFException
  2. Java EOFException
  3. Java でストリームから読み取る際の EOFException を回避する
Java で EOFException を処理する

この記事では、JavaIOException のサブクラスとしての JavaEOFException と、Java で EOFException を処理する方法について説明します。

JavaIOException のサブクラスとしての JavaEOFException

Java EOFException は、サブクラスまたは特定のタイプの Java IOException であるため、EOFException を理解するには IOException を知っている必要があります。

Java は IOException をスローして、実行中にプログラムに入力または出力操作による中断が発生したことを通知します。

IOException はチェックされた例外です。つまり、例外を正しく処理する必要があります。try/catch ブロックを使用するか、例外を再度スローすることで、例外を処理できます。

例外を処理しない場合、JVM は例外を処理し、プログラムの実行を終了します。

JavaIOException の例

ストリームからデータを読み取っている可能性があり、他のプログラムが操作中にストリームを閉じます。この場合、Java は IOException クラスオブジェクトをスローすることによって IOException を発生させます。

発生した IOException の他の例には、サーバーからの読み取り中のネットワーク障害、ディスク容量が少ないためにファイルに書き込めないこと、およびその他のファイル処理操作が含まれます。

例:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ExceptionExample {
  public static void main(String[] args) {
    File file = new File("MyFile.txt", "r");
    try {
      FileReader fr = new FileReader(file.getAbsoluteFile());
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

出力:

java.io.FileNotFoundException: /home/stark/eclipse-workspace-java/JavaArticles/MyFile.txt/r (No such file or directory)
    at java.base/java.io.FileInputStream.open0(Native Method)
    at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
    at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
    at java.base/java.io.FileReader.<init>(FileReader.java:75)
    at ExceptionExample.main(ExceptionExample.java:12)

コードは try/catch ブロックを使用して例外を処理することに注意してください。

また、ほとんどの場合、IOException オブジェクトは直接スローされないことに注意する必要があります。代わりに、発生した例外に従って、そのサブクラスオブジェクトの 1つがスローされます。

Java EOFException

Java プログラムは、実行が予期せずファイルの終わりまたはストリームの終わりに達すると、EOF(ファイルの終わり)例外を発生させます。この例外は、ストリームオブジェクトを使用してファイルからコンテンツを読み取るときに発生します。

ファイルの終わりに達したら、ファイルを終了する必要があります。ただし、プログラムがそれでもファイルを読み取ろうとすると、Java は EOFException を発生させます。

このタイプの例外は、チェックされた例外でもあります。

例:

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExceptionExample {
  public static void main(String[] args) {
    File file = new File("/home/stark/eclipse-workspace-java/JavaArticles/src/MyFile.txt");
    try {
      DataInputStream dis = new DataInputStream(new FileInputStream(file));
      int data;
      while (true) {
        data = dis.readInt();
        System.out.println(data);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (EOFException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

出力:

1629512224
1663067168
1696622112
1730177056
1763732000
1797286944
1830842144
java.io.EOFException
    at java.base/java.io.DataInputStream.readInt(DataInputStream.java:397)
    at ExceptionExample.main(ExceptionExample.java:20)

この例では、コードは無限ループのストリームを使用してファイルを継続的に読み取ります。したがって、ファイルの終わりに達した後でも、コードはストリームから読み取ろうとします。

これが、EOFException が発生する理由です。

コードは try/catch ブロックを使用して EOFException を処理し、例外につながるスタックトレースまたは実行のトレースを出力することに注意してください。

Java でストリームから読み取る際の EOFException を回避する

ファイルの終わりに達したらすぐにファイルの読み取り操作を正しく終了すれば、コード内の EOFException を回避できます。

EOFException を回避するために、上記のサンプルコードの変更を見てみましょう。

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExceptionExample {
  public static void main(String[] args) {
    File file = new File("/home/stark/eclipse-workspace-java/JavaArticles/src/MyFile.txt");
    int data = 0;
    try {
      DataInputStream dis = new DataInputStream(new FileInputStream(file));

      while (dis.available() > 4) {
        data = dis.readInt();
        System.out.println(data);
      }
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (EOFException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

出力:

1629512224
1663067168
1696622112
1730177056
1763732000
1797286944
1830842144

コードが例外をスローしないことがわかります。このコードは、ストリームに 4 バイト未満の場合、ループが終了するという条件を定義しています。

これは、Java では整数のサイズが 4 バイトであるためです。それに応じて、読み取り操作を終了するための条件を定義できます。

または、catch ブロックを使用して、例外がスローされた後に読み取り操作を終了することもできますが、推奨されるべきではありません。ただし、catch ブロックを使用して、予期しない入力を回避できます。

関連記事 - Java Exception