我是java tutorials之后的初学java程序员。
我正在使用Java tutorials的Data Streams Page中的简单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 tutorials的Data Streams Page,它说:
请注意,DataStreams通过捕获EOFException来检测文件结束条件,而不是测试无效的返回值。 DataInput方法的所有实现都使用EOFException而不是返回值。
那么,这是否意味着捕获EOFException
是正常的,所以只是捕获它而不处理它很好,这意味着文件的末尾已经到达了?
如果这意味着我应该处理它,请告诉我如何操作。
修改
根据建议,我已使用in.available() > 0
修复while
循环条件。
或者,我无法处理异常,因为它很好。
答案 0 :(得分:20)
从文件中读取时,您的循环不会终止。因此,它读取所有值,正确在下面的读取的下一次迭代中抛出EOFException:
price = in.readDouble();
如果您阅读文档,则说:
抛出:
EOFException - 如果此输入流在读取八个字节之前到达结尾。
IOException - 流已关闭且包含的输入流在关闭后不支持读取,或发生另一个I / O错误。
在while循环中设置正确的终止条件以解决问题,例如下面:
while(in.available() > 0) <--- if there are still bytes to read
答案 1 :(得分:5)
处理此问题的最佳方法是以适当的条件终止无限循环。
但是因为你要求进行异常处理:
尝试使用两次捕获。您的EOFException是预期的,因此在发生时似乎没有问题。应该处理任何其他例外。
...
} catch (EOFException e) {
// ... this is fine
} catch(IOException e) {
// handle exception which is not expected
e.printStackTrace();
}
答案 2 :(得分:2)
您可以使用while(in.available() != 0)
代替while(true)
。
答案 3 :(得分:2)
或者,您可以使用:
首先写出元素数量(作为标题)out.writeInt(prices.length);
当您阅读文件时,首先阅读标题(元素计数):
int elementCount = in.readInt();
for (int i = 0; i < elementCount; i++) {
// read elements
}
答案 4 :(得分:0)
你抓住IOException
也会抓住EOFException
,因为它是继承的。如果你看一下tutorial中的例子,他们强调你应该抓住EOFException
- 这就是他们所做的。要解决问题,请在EOFException
之前抓住IOException
:
try
{
//...
}
catch(EOFException e) {
//eof - no error in this case
}
catch(IOException e) {
//something went wrong
e.printStackTrace();
}
除此之外我不喜欢使用异常的数据流控制 - 它不是异常的预期用途,因此(在我看来)非常糟糕的风格。
答案 5 :(得分:0)
将您的代码放在try catch块中: 即:
try{
if(in.available()!=0){
// ------
}
}catch(EOFException eof){
//
}catch(Exception e){
//
}
}
答案 6 :(得分:0)
您可能会遇到从InputStream
读取并使用代码段的代码
while(in.available()>0)
检查流的结尾,而不是检查
EOFException(文件末尾)。
此技术的问题,Javadoc
确实反映了这一点,因为它仅告诉您可以读取的块数,而不会阻止下一个调用者。换句话说,即使还有更多字节要读取,它也可以return 0
。因此,永远不要使用InputStream available()
方法检查流的结尾。
您必须使用while (true)
和
catch(EOFException e) {
//This isn't problem
} catch (Other e) {
//This is problem
}
答案 7 :(得分:0)
EOFException 是 IOException 的子代 我更喜欢下面的 ==>
try {
.
.
.
} catch (IOException e) {
if (!(e instanceof EOFException)) {
throw new RuntimeException(e);
}
}