Win a copy of Practical SVG this week in the HTML/CSS/JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

How should streams be closed?

 
Raf Szczypiorski
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi. I am having this question because I noticed something while working on a Linux system. Consider this code:

When I debugged, and the close() was skipped when an exception happened, lsof (list open files) command showed that a given file is still open. So, I coined something like this:

So, when the faulty read is performed, the finally block is executed even if an exception is thrown, and the cause is then rethrown. Of ocurse, if everything is allright, it is also closed. lsof reported that the file handle is propertly closed, so it behaves the way it should. The same is probably also true for socket streams and so on.
I am writing this as we have a system that opens a large amount of files, and in some circumstances (lots of read exceptions) the user owning the process would run out of available file handles. This fix solved the issue.
Also, I am collecting info for my SCJD exam, and I am pretty sure I will have to use streams there, and I will have to do it correctly to keep the points ;-0

I have read many Java books, but I have never seen any mention of a file stream not being closed when an exception happens in any book, though. They always keep saying that you (a good and friendly developer) should always release all the resources when you don't need them any more, so call close() on the stream in this case, but they actually never do it like I am showing now.
So, the question is - how do you handle this? Is my approach correct or am I exagerrating a bit? Maybe there is a different, better, way?

Raf
 
Joe Ess
Bartender
Posts: 9362
11
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have a look at our FAQ: TooManyOpenFiles. Using a finally block is the Best Practice.
 
Raf Szczypiorski
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the link and your answer.

This code in the FAQ catches the exception, and my example doesn't. What if your code is in a method, and you actually want to propagate the exception higher in the call hierarchy? I guess you would rethrow it in the catch, but it is almost the same as my try - finally without catch, but more complex? Please correct me if I am wrong.

Raf
 
Joe Ess
Bartender
Posts: 9362
11
Linux Mac OS X Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The finally block executes before control is handed back to the caller. This is easy enough to test:


If you compile and run this example, you'll see the following output:


So we throw an exception, the catch block catches it, constructs a new exception and throws it. Before the VM goes up the call stack looking for a handler for the second exception, it will run the finally block in this method. After running the finally block, there's only one caller, the VM itself, which handles the second exception by printing out the stack trace.
 
Raf Szczypiorski
Ranch Hand
Posts: 383
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, that's what I meant. I just said that the solution with a try - catch - finally with a catch that only rethrows is more complex than try - finally with implicit rethrow. I meant not to argue or undermine anything
Thank you, from now on finally is my friend when it comes to streams
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!