ZetCode

Java EOFException 类

最后修改时间:2025 年 4 月 16 日

java.io.EOFException 信号表示在输入期间意外到达文件或流的末尾。它扩展了 IOException,并在读取超过文件或流的末尾时抛出。此异常有助于检测意外的 end-of-file (EOF) 状态。

EOFException 通常在读取基本数据类型时由数据输入流抛出。与正常的 end-of-file 检测(返回 -1)不同,此异常表示意外终止。它是一个已检查异常,必须被捕获或声明。

EOFException 类概述

EOFException 扩展了 IOException,并且不提供其他方法。它作为一种特定的 I/O 异常类型。该类是可序列化的,并遵循标准的异常处理模式。

public class EOFException extends IOException {
    public EOFException();
    public EOFException(String s);
}

上面的代码展示了 EOFException 的简单结构。它提供了两个构造函数 - 一个默认构造函数和一个带消息的构造函数。消息可以提供有关意外 end-of-file 状态的详细信息。

基本 EOFException 示例

此示例演示了在从数据流读取时如何发生 EOFException。我们将使用 DataInputStream,它在读取超过文件末尾时抛出此异常。

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

public class Main {

    public static void main(String[] args) {
        try (DataInputStream dis = 
                new DataInputStream(new FileInputStream("data.bin"))) {
            
            while (true) {
                int value = dis.readInt();
                System.out.println("Read value: " + value);
            }
            
        } catch (EOFException e) {
            System.out.println("End of file reached");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例尝试从二进制文件读取整数直到 EOF。DataInputStream.readInt 在无法读取完整的 int 时抛出 EOFException。我们捕获此异常以处理正常的文件结束状态。

使用基本类型处理 EOFException

当读取基本数据类型时,通常会遇到 EOFException。每个基本类型都有一个固定大小,读取部分数据会触发异常。此示例展示了如何处理多种基本类型。

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

public class Main {

    public static void main(String[] args) {
        try (DataInputStream dis = 
                new DataInputStream(new FileInputStream("mixed_data.bin"))) {
            
            while (true) {
                try {
                    int i = dis.readInt();
                    double d = dis.readDouble();
                    boolean b = dis.readBoolean();
                    
                    System.out.printf("Read: %d, %.2f, %b%n", i, d, b);
                } catch (EOFException e) {
                    System.out.println("Finished reading complete records");
                    break;
                }
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例读取一系列 int、double 和 boolean 值。内部 try-catch 处理当无法读取完整记录时发生的 EOFException。这种方法允许处理完整的记录,同时优雅地处理部分记录。

使用 ObjectInputStream 的 EOFException

当反序列化对象时,EOFException 信号表示有效对象的结束。此示例演示了读取多个序列化对象直到 EOF。该异常标记了对象流的结束。

Main.java
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Main {

    public static void main(String[] args) {
        try (ObjectInputStream ois = 
                new ObjectInputStream(new FileInputStream("objects.dat"))) {
            
            System.out.println("Reading objects:");
            
            while (true) {
                try {
                    Object obj = ois.readObject();
                    System.out.println("Read object: " + obj);
                } catch (ClassNotFoundException e) {
                    System.out.println("Unknown class found");
                }
            }
            
        } catch (EOFException e) {
            System.out.println("End of object stream reached");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例读取序列化对象,直到发生 EOFException。该异常表明没有更多对象可用。请注意,我们还处理了反序列化期间可能发生的 ClassNotFoundException

文件读取中的自定义 EOF 处理

此示例展示了如何在读取字节时实现自定义的 end-of-file 处理。我们将标准方法(返回 -1)与来自数据流的 EOFException 进行比较。

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

public class Main {

    public static void main(String[] args) {
        // Standard byte reading (returns -1 at EOF)
        try (FileInputStream fis = new FileInputStream("data.txt")) {
            int byteRead;
            while ((byteRead = fis.read()) != -1) {
                System.out.print((char) byteRead);
            }
            System.out.println("\nStandard EOF reached");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // DataInputStream reading (throws EOFException)
        try (DataInputStream dis = 
                new DataInputStream(new FileInputStream("data.txt"))) {
            while (true) {
                byte b = dis.readByte();
                System.out.print((char) b);
            }
        } catch (EOFException e) {
            System.out.println("\nDataInputStream EOF reached");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

该示例对比了两种 EOF 检测方法。FileInputStream.read 在 EOF 处返回 -1,而 DataInputStream.readByte 抛出 EOFException。这两种方法都有效,但在不同的上下文中被使用。

使用 Available 检查防止 EOFException

我们可以在读取之前通过检查可用字节来防止 EOFException。此示例展示了如何使用 available 来避免在读取固定大小的数据时发生异常。

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

public class Main {

    public static void main(String[] args) {
        try (DataInputStream dis = 
                new DataInputStream(new FileInputStream("data.bin"))) {
            
            while (dis.available() >= Integer.BYTES) {
                int value = dis.readInt();
                System.out.println("Read integer: " + value);
            }
            
            System.out.println("Remaining bytes: " + dis.available());
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此方法在读取整数之前检查是否有足够的字节可用。Integer.BYTES 给出了一个 int 的大小(4 个字节)。这通过确保在读取之前有完整的数据来防止 EOFException

Random Access Files 中的 EOFException

当读取超过文件末尾时,EOFException 可能会发生在 RandomAccessFile 中。此示例演示了在使用随机文件访问时正确处理的方法。

Main.java
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Main {

    public static void main(String[] args) {
        try (RandomAccessFile raf = 
                new RandomAccessFile("random.dat", "r")) {
            
            // Move to end minus 4 bytes (size of int)
            raf.seek(raf.length() - Integer.BYTES);
            System.out.println("Last int: " + raf.readInt());
            
            // Attempt to read past EOF
            try {
                raf.readInt();
            } catch (EOFException e) {
                System.out.println("Caught EOFException as expected");
            }
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例展示了使用 RandomAccessFileEOFException 处理。我们首先成功读取最后一个 int,然后演示在读取超过 EOF 时发生的异常。文件位置可以使用 seek 进行控制。

来源

Java EOFException 类文档

在本文中,我们涵盖了 Java EOFException 类的基本方面。理解此异常对于正确处理 Java I/O 操作中的 end-of-file 状态至关重要。

作者

我的名字是 Jan Bodnar,是一位经验丰富的程序员,在该领域拥有多年经验。我于 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和 8 本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程