Are dereferenced open streams implicitly closed?
August 28, 2009 8:32 AM Subscribe
Java filter: Are dereferenced InputStreams implicitly closed?
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.
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.
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:
posted by flif at 11:59 AM on August 28, 2009
InputStream s = new FileInputStream(....);
try {
s.read(...); // this can fail
}
finally {
s.close();
}
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
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
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
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
This thread is closed to new comments.
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