EOFException - 如何处理?

Jon*_*Lam 20 java exception try-catch

我是一个初学java程序员,遵循java教程.

我正在使用Java教程数据流页面中的一个简单的Java程序,并且在运行时,它一直在显示EOFException.我想知道这是否正常,因为读者必须最终到达文件的末尾.

import java.io.*;

public class DataStreams {
    static final String dataFile = "F://Java//DataStreams//invoicedata.txt";

    static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
    static final int[] units = { 12, 8, 13, 29, 50 };
    static final String[] descs = {
        "Java T-shirt",
        "Java Mug",
        "Duke Juggling Dolls",
        "Java Pin",
        "Java Key Chain"
    };
    public static void main(String args[]) {
        try {
            DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dataFile)));

            for (int i = 0; i < prices.length; i ++) {
                out.writeDouble(prices[i]);
                out.writeInt(units[i]);
                out.writeUTF(descs[i]);
            }

            out.close(); 

        } catch(IOException e){
            e.printStackTrace(); // used to be System.err.println();
        }

        double price;
        int unit;
        String desc;
        double total = 0.0;

        try {
            DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile)));

            while (true) {
                price = in.readDouble();
                unit = in.readInt();
                desc = in.readUTF();
                System.out.format("You ordered %d" + " units of %s at $%.2f%n",
                unit, desc, price);
                total += unit * price;
            }
        } catch(IOException e) {
            e.printStackTrace(); 
        }

        System.out.format("Your total is %f.%n" , total);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译很好,但输出是:

You ordered 12 units of Java T-shirt at $19.99
You ordered 8 units of Java Mug at $9.99
You ordered 13 units of Duke Juggling Dolls at $15.99
You ordered 29 units of Java Pin at $3.99
You ordered 50 units of Java Key Chain at $4.99
java.io.EOFException
        at java.io.DataInputStream.readFully(Unknown Source)
        at java.io.DataInputStream.readLong(Unknown Source)
        at java.io.DataInputStream.readDouble(Unknown Source)
        at DataStreams.main(DataStreams.java:39)
Your total is 892.880000.
Run Code Online (Sandbox Code Playgroud)

Java教程数据流页面,它说:

请注意,DataStreams通过捕获EOFException来检测文件结束条件,而不是测试无效的返回值.DataInput方法的所有实现都使用EOFException而不是返回值.

那么,这是否意味着捕获EOFException是正常的,所以只是捕获它而不是处理它很好,这意味着文件的结尾已经达到了?

如果这意味着我应该处理它,请告诉我如何做到这一点.

编辑

从建议中,我通过使用固定它in.available() > 0while循环条件.

或者,我无法处理异常,因为它很好.

Yog*_*ngh 22

从文件中读取时,您的循环不会终止.所以它读取所有值并在下面的读取的下一次迭代中正确抛出EOFException:

 price = in.readDouble();
Run Code Online (Sandbox Code Playgroud)

如果您阅读文档,它会说:

抛出:

EOFException - 如果此输入流在读取八个字节之前到达结尾.

IOException - 流已关闭,并且包含的​​输入流在关闭后不支持读取,或发生另一个I/O错误.

在while循环中设置适当的终止条件以解决问题,例如:

     while(in.available() > 0)  <--- if there are still bytes to read
Run Code Online (Sandbox Code Playgroud)

  • 当没有更多数据*当前可读取*,并且*不是*仅在流末尾时,此循环将退出。InputStream.available()不是流结束的测试。请参阅Javadoc。 (2认同)

Mar*_*ler 6

解决此问题的最佳方法是在适当条件下终止无限循环。

但是由于您要求进行异常处理:

尝试使用两个锁扣。您的EOFException是预期的,因此发生时似乎没有问题。任何其他异常都应处理。

...
} catch (EOFException e) {
   // ... this is fine
} catch(IOException e) {
    // handle exception which is not expected
    e.printStackTrace(); 
}
Run Code Online (Sandbox Code Playgroud)