Strange behavior of EOFException

125 views Asked by At

I have some simple class that is DataInputStream stream to read from file.

I have surrounded this stream with EOFException try-catch block.

It has some strange behavior coz sometimes it throws EOFException into text that is read.

Output to console:

"The vessel was in as good condition as I am, and as, I hope
you ar#End of streame#, M. Morrel, and this day and a half was lost from
pure whim, for the pleasure of going ashore, and nothing
else."

I couldn't figure out what is cause of this strange behavior...

Here is code snippet:

public class FormattedMemoryInput {    
    public static void main(String[] args) throws IOException {
        boolean done = false;    
        try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(
                BufferedInputFile.read("./gutenberg/cristo.txt").getBytes()));) {

            while (!done) {
                System.out.print((char) in.readByte());
            }
        } catch (EOFException e) {
            System.err.println("#End of stream#");
        }
    }
} 

It uses static method BufferedInputFile.read() to read first 500 lines:

public class BufferedInputFile {

    // Throw exceptions to console:
    public static String read(String filename) throws IOException {

        // Reading input by lines:
        BufferedReader in = new BufferedReader(new FileReader(filename));
        StringBuilder sb = new StringBuilder();
        String s;
        int i = 0;

        while ((s = in.readLine()) != null && (i < 500)) {
            sb.append(s + "\n");
            i++;
        }

        in.close();
        return sb.toString();
    }
  • Why EOFException is thrown into text?

Solution:

It was at adding one line:

while (!done) {
    System.out.print((char) in.readByte());
    System.out.flush(); // this one
}
2

There are 2 answers

0
chrylis -cautiouslyoptimistic- On BEST ANSWER

System.out is buffered by default; System.err isn't. If you redirect one of the output streams, either in your program or from the shell, you should see the output in the expected order. You can force System.out to print its output by calling System.out.flush();; try inserting that at the end of your while loop.

0
Jon Skeet On

Well, you're getting an EOFException because you're reading forever - you never change the value of done.

The reason it's appearing in the middle of the text instead of at the end is that you're using System.err to print in the exceptional case, and System.out to print the main text. Those are separate streams, flushed separately. If you flush System.out before writing to System.err, I suspect you'll see the main text before the error message. (Note that you're using println on System.err, which will flush automatically, but just print on System.out, which won't.)

There are various other things I'd change about the code - particularly the use of String.getBytes() without specifying an encoding - but assuming I've understood your question correctly, the difference in streams is the reason you're looking for.