Are dereferenced open streams implicitly closed?
August 28, 2009 8:32 AM   Subscribe

Java filter: Are dereferenced InputStreams implicitly closed?

InputStream s;
s = new InputStream(filename1);

... // filename1 is read and used.

// Ok, I'm done with filename1, but I want to reuse s to open filename2

s = new InputStream(filename2);

Does calling a new instance of s implicitly call s.close() to close the filename1 stream before opening the new stream?

Or is filename1 stream just now dereferenced open stream?

I ask because I ran into the "too many files open" exception when I ran my program on Fedora. So, while I was in the process of cleaning up my code and making sure I closed all InputStreams, it dawned on me that reusing an InputStream variable without first explicitly calling close() might not close the old stream. Is this true?

Also, I'm aware that you can increase the # of open files limit in Linux, but I'd rather stick to good coding practices instead of a band-aid solution.
posted by nikkorizz to Computers & Internet (5 answers total)
No it does not. You should always close the input streams when you are finished with them to ensure that the underlying file descriptors are properly closed.

Assuming these are FileInputStreams, the garbage collector will call dispose() on them when it destroys them, but there is no guarantee that the garbage collector will ever reclaim the first input stream. And in practice, it probably will not unless the JVM gets low on memory.
posted by Khalad at 8:39 AM on August 28, 2009

And always use try...finally around the code that reads from the stream, so the stream gets closed if you get an exception while reading from the stream:

InputStream s = new FileInputStream(....);
try {; // this can fail
finally {

posted by flif at 11:59 AM on August 28, 2009

In general, good programming practice is to explicitly release/close any resources instead of relying on implicit behavior.
posted by kenliu at 8:14 PM on August 29, 2009

Close for sure... not exactly the same issue, but I was debugging someone's code a while back where they weren't closing their JDBC Statement objects correctly - they couldn't understand why it was that the Connection was eventually complaining that it couldn't create a Statement.

Also: on OutputStreams, alwasy remember to flush()! :)
posted by lowlife at 8:28 AM on August 31, 2009

1) Closing in a finally block is the best way to get this behavior.
2) That's not what dereference means. I would describe your situation as "overwriting the last reference to the stream." Notice that in general, it would be a mistake if the stream were automatically closed at that point - you could have passed the stream to a function and stored a reference elsewhere.
posted by Horselover Fat at 11:05 PM on August 31, 2009

« Older What Toronto bar would suit a book club meeting?   |   (3Excel)*(2Help)*(1Please) Newer »
This thread is closed to new comments.