EOFException – 如何处理?

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

我正在使用Java教程的Data Streams页面中的一个简单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); } } 

编译很好,但输出是:

 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. 

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

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

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

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

编辑

根据建议,我通过使用in.available() > 0来修复它,用于while循环条件。

或者,我无法处理exception,因为它很好。

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

  price = in.readDouble(); 

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

抛出:

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

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

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

  while(in.available() > 0) <--- if there are still bytes to read 

处理此问题的最佳方法是使用适当的条件终止无限循环。

但是因为你要求进行exception处理:

尝试使用两次捕获。 您的EOFException是预期的,因此在发生时似乎没有问题。 应该处理任何其他例外。

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

您可以使用while(in.available() != 0)而不是while(true)

或者,您可以使用以下方法首先写出元素数量(作为标题):

 out.writeInt(prices.length); 

当您读取文件时,首先阅读标题(元素计数):

 int elementCount = in.readInt(); for (int i = 0; i < elementCount; i++) { // read elements } 

您捕获IOException ,它也捕获EOFException ,因为它是inheritance的。 如果你看一下教程中的例子,他们强调你应该捕获EOFException – 这就是他们所做的。 要解决您的问题,请在IOException之前捕获EOFException

 try { //... } catch(EOFException e) { //eof - no error in this case } catch(IOException e) { //something went wrong e.printStackTrace(); } 

除此之外,我不喜欢使用exception的数据流控制 – 它不是exception的预期用途,因此(在我看来)非常糟糕的风格。

将您的代码放在try catch块中:ie:

 try{ if(in.available()!=0){ // ------ } }catch(EOFException eof){ // }catch(Exception e){ // } }