Re: Closing decorated streams
On Thu, 9 Jul 2009, Philipp wrote:
Hello, I use the following code but am not sure that it is the best or
correct way to close the stream. In particular, if url.openStream()
succeeds I have an open stream, but if any of the two other
constructors throws an exception, reader will be null and the stream
will remain open even after the finally block.
In this case, i'd exploit the knowledge that the upper-layer streams are
lightweight, and don't really need to be closed - if they aren't closed
but are garbage collected, that's fine. So i'd do:
InputStream urlStream = url.openStream();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(urlStream));
// use reader
}
finally {
urlStream.close();
}
In the more general case, where you might have another heavyweight stream
that needs to be explicitly closed in the stack, i'd think about keeping a
pointer to the topmost stream, so i could just close that. Since that
stream could actually be a reader, i'd make the variable a Closeable. Like
so:
InputStream urlStream = url.openStream();
Closeable topStream = urlStream;
try {
Reader isr = new InputStreamReader(urlStream)'
topStream = isr;
BufferedReader reader = new BufferedReader(isr);
topStream = reader;
// use reader here
}
finally {
topStream.close();
}
Yes, you have to write out each construction as a separate statement, and
then add a line to update topStream. But at least you only have to do the
closing once. Note that you actually only have to do the separation and
updating for each heavyweight stream in the stack - lightweight streams
can be constructed inline. Like (assuming GZIPInputStream uses libgzip
with a native context object - i could be wrong about that):
InputStream urlStream = url.openStream();
Closeable topStream = urlStream;
try {
InputStream gz = new GZIPInputStream(new BufferedInputStream(urlStream));
topStream = gz;
BufferedReader reader = new BufferedReader(new InputStreamReader(gz));
// use reader here
}
finally {
topStream.close();
}
tom
--
I have been trying to find a way of framing this but yes, a light meal is
probably preferable to a heavy one under the circumstances. -- ninebelow