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){ // } }