Win a copy of Java 9 Modularity: Patterns and Practices for Developing Maintainable Applications this week in the Java 9 forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

EOF comes in different places  RSS feed

 
Frederico Bruno
Greenhorn
Posts: 10
Chrome Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'm reading a file a byte at a time (always the same) and sometimes I read with no problem, other times it gives me an EOF in different executions of the loop.
Can anyone give me a hint why this erratic behavior happens?

Here is the code:
 
Joe Ess
Bartender
Posts: 9436
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the JavaRanch.
I don't see anything obviously wrong with this code. Reading byte-by-byte is slow, but other than that, it should work.
Can you share the stack trace from one of your exceptions with us?
 
Frederico Bruno
Greenhorn
Posts: 10
Chrome Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here goes, but it really doesn't say much:


Apparently it only happens when I'm debugging...

This time occured in the byte 533 (the file is 570 bytes long).
Other times occurred in 564 and 568.
[ April 16, 2008: Message edited by: Frederico Bruno Ferreira ]
 
Joe Ess
Bartender
Posts: 9436
12
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What does ioe.getCause() return?
What debugger are you using? Does it happen only if you are stepping through code, or even if you just have the debugger hooked up?
One of my coworkers complained about getting random exceptions until I sat down with her and saw she was taking so long to step through some EJB code the underlaying database connections were timing out. Of course, they have explicit timeouts. Files don't.
 
Frederico Bruno
Greenhorn
Posts: 10
Chrome Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What does ioe.getCause() return?
- java.io.EOFException

What debugger are you using?
- Eclipse: to be more precise: BEA WorkSpace Studio

Does it happen only if you are stepping through code, or even if you just have the debugger hooked up?
- It only happened when I was stepping through

Yes, files don't have timeouts.
I'm suspecting that one of the streams, but really don't see how.

In any case, thanks for loosing your time with this!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
One issue here is that your exception handling may have lost some information:

You catch an IOException, and then you pass on the file name and the getCause(). However it's possible that there was additional information here. The original exception may have had a message, for example. And it may have been a particular subclass of IOException - sometimes the name of the exception is itself important information.

I think the most effective way to handle this is to pass on the original exception, not the getCause() exception:

Notice that not only did I replace ioe.getCause() with ioe, but I also added + ioe to the ClientException message. Typically toString() does a good job of telling us both the class and message of the exception that was thrown, which is a useful summary.

If you make this change, you may or may not get more information about the problem. If you look carefully at the stack trace, you should see that the information about the cause is still there. Even if you don't get new useful information, I think it's worthwhile in general to be careful not to discard information from the exception.

Aside from this, I don't see anything in your code that would explain the results you're getting. Is it possible that whatever process wrote the file is still running? Perhaps the writer has not closed properly yet? Or something is rewriting the file while you're reading it?

You really should close() the input stream (preferably in a finally{} block) when you're done with it, by the way. That wouldn't explain the problem you're observing, but it's a good practice anyway. Otherwise you may get strange results the next time you try to access the file.
 
Frederico Bruno
Greenhorn
Posts: 10
Chrome Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the suggestions.

I still didn't found the reason why it happened, but since it only occurred in debug and while running through the code, I'm not going to loose much more time with it (I'll try to understand it latter in the future).

I'm adopting some of the points both of you made:
1 - Reading in byte chunks;
2 - Pass the entire exception information;
3 - Closing the stream inside a finally block

In the end, the code goes like:


How does it look now?

(EDIT: I removed the dumb question I posted!)

[ April 18, 2008: Message edited by: Frederico Bruno Ferreira ]
[ April 18, 2008: Message edited by: Frederico Bruno Ferreira ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That looks good to me. I see two minor potential problems. One is that the input stream is closed, but not the output stream. The other is throwing an exception from the finally block. In theory it's possible that the read() or write() might throw an exception, and then when you call close(), that close() might throw another exception. If this happens, you would lose any information about the original exception. So it may be preferable to do something like this instead:

Here the idea is that if there's an error during the close, the most we can do is report the error (I used printStackTrace(), but logging may be preferable). We don't really want to throw an exception here since that may lose the information from a previous exception. The downside is that if there was no previous exception, maybe we should have thrown a new ClientException here. Another alternative is something like this:
Here the idea is we'll throw a new exception for whatever the first exception is, even if it occurs during a close(). But any later exception will not generate a new ClientException. It should not be a problem if the streams get closed twice - the second close simply has no effect.

In practice, the differences between these options don't matter much, because it's extremely rare (in my experience) that a close() might generate a new exception after the original exception. Most streams are designed so that close() only throws an exception if there's a new problem. However this isn't really guaranteed. Since you asked, I'm giving a detailed answer, even though it's kind of worrying about things that almost never happen. It's up to you how detailed you want to make your error-handling code in these cases.
 
Frederico Bruno
Greenhorn
Posts: 10
Chrome Java Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks.

Glad you put a detailed answer.
It helps to learn a bit more.


Frederico
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!