EOFException - how to handle?

162,017

Solution 1

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

 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.

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

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

Solution 2

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.

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

Solution 3

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
}

Solution 4

You may come across code that reads from an InputStream and 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).

The problem with this technique, and the Javadoc does 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 0 even 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.

You must use while (true) and

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

Solution 5

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

Share:
162,017
Jonathan Lam
Author by

Jonathan Lam

#SOreadytohelp

Updated on July 09, 2022

Comments

  • Jonathan Lam
    Jonathan Lam almost 2 years

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

    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.

    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 $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.
    

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

    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.

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

    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() > 0 for the while loop condition.

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