Java EOFException - 如何处理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18451232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:43:13  来源:igfitidea点击:

EOFException - how to handle?

javaexceptiontry-catch

提问by Jonathan Lam

I'm a beginner java programmer following the java tutorials.

我是遵循java 教程的初学者 java 程序员。

I am using a simple Java Program from the Java tutorials's Data Streams Page, and at runtime, it keeps on showing EOFException. I was wondering if this was normal, as the reader has to come to the end of the file eventually.

我正在使用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);
    }
}

It compiles fine, but the output is:

它编译得很好,但输出是:

You ordered 12 units of Java T-shirt at .99
You ordered 8 units of Java Mug at .99
You ordered 13 units of Duke Juggling Dolls at .99
You ordered 29 units of Java Pin at .99
You ordered 50 units of Java Key Chain at .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.

From the Java tutorials's Data Streams Page, it says:

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

Notice that DataStreams detects an end-of-file condition by catching EOFException, instead of testing for an invalid return value. All implementations of DataInput methods use EOFException instead of return values.

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

So, does this mean that catching EOFExceptionis normal, so just catching it and not handling it is fine, meaning that the end of file is reached?

那么,这是否意味着捕获EOFException是正常的,所以只捕获它而不处理它就可以了,这意味着到达文件末尾吗?

If it means I should handle it, please advise me on how to do it.

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

EDIT

编辑

From the suggestions, I've fixed it by using in.available() > 0for the whileloop condition.

根据建议,我已经通过使用in.available() > 0forwhile循环条件修复了它。

Or, I could do nothing to handle the exception, because it's fine.

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

采纳答案by Yogendra Singh

While reading from the file, your are not terminating your loop. So its read all the values and correctlythrows EOFException on the next iteration of the read at line below:

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

 price = in.readDouble();

If you read the documentation, it says:

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

Throws:

EOFException - if this input stream reaches the end before reading eight bytes.

IOException - the stream has been closed and the contained input stream does not support reading after close, or another I/O error occurs.

抛出:

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

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

Put a proper termination condition in your while loop to resolve the issue e.g. below:

在你的 while 循环中放置一个适当的终止条件来解决这个问题,例如:

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

回答by akaHuman

You can use while(in.available() != 0)instead of while(true).

您可以使用while(in.available() != 0)代替while(true).

回答by Martin Seeler

The best way to handle this would be to terminate your infinite loop with a proper condition.

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

But since you asked for the exception handling:

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

Try to use two catches. Your EOFException is expected, so there seems to be no problem when it occures. Any other exception should be handled.

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

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

回答by Jost

You catch IOExceptionwhich also catches EOFException, because it is inherited. If you look at the example from the tutorialthey underlined that you should catch EOFException- and this is what they do. To solve you problem catch EOFExceptionbefore IOException:

您捕获IOException哪个也捕获EOFException,因为它是继承的。如果您查看教程中的示例,他们强调您应该抓住EOFException- 这就是他们所做的。要解决您EOFException之前的问题 catch IOException

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

Beside that I don't like data flow control using exceptions - it is not the intended use of exceptions and thus (in my opinion) really bad style.

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

回答by Katona

Alternatively, you could write out the number of elements first (as a header) using:

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

out.writeInt(prices.length);

When you read the file, you first read the header (element count):

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

int elementCount = in.readInt();

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

回答by Sudarshan Nagre

Put your code inside the try catch block: i.e :

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

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

回答by Taleh Alqayev

You may come across code that reads from an InputStreamand uses the snippet while(in.available()>0)to check for the end of the stream, rather than checking for an EOFException (end of the file).

您可能会遇到从 读取InputStream并使用代码片段while(in.available()>0)检查流末尾的代码 ,而不是检查 EOFException(文件末尾)。

The problem with this technique, and the Javadocdoes echo this, is that it only tells you the number of blocks that can be read without blocking the next caller. In other words, it can return 0even if there are more bytes to be read. Therefore, the InputStream available()method should never be used to check for the end of the stream.

这种技术的问题Javadoc是它只告诉你可以读取的块数,而不会阻塞下一个调用者。换句话说,return 0即使有更多字节要读取,它也可以。因此,InputStream available()永远不应该使用该方法来检查流的结尾。

You must use while (true)and

您必须使用while (true)

catch(EOFException e) {
//This isn't problem
} catch (Other e) {
//This is problem
}