• Post Reply Bookmark Topic Watch Topic
  • New Topic

Will close one of three linked streams close them all?  RSS feed

 
Jason Stortz
Ranch Hand
Posts: 68
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is the code in question:

And my question is...what is the proper way to close these? So far my thoughts include:

which closes them in the opposite order they were opened. Or, can I take the topmost part of the linked streams, a.k.a. the z object and simply close it by itself?
z.close();
Please advise on what to do, and if possible explain why.
Thanks in advance.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As far as I can tell, for all the stream classes which wrap around underlying streams, a call to close() for the outer (higher-level) stream will also close the inner (lower-level) stream. So you should be able to get away with simply calling z.close(); nothing else is needed. However, this behavior does not seem to be explicitly guaranteed by the API - I had to look at source code to verify it, and I didn't look at every class. So I suppose the proper, safe way to do this is to explicitly close each stream. There's nothing wrong with closing a stream that has already been closed; it doesn't do anything other than waste a couple extra JVM cycles. So, better safe than sorry I suppose. Furthermore, you need to consider what happens if an IOException is thrown while trying to open a high-level stream. You won't be able to close the high-level stream, since there's nothing to close; it doesn't exist. But the low-level stream was already created, and still needs to be closed. This can be handled as follows:
<code><pre>
public static void unzip(String fileName) throws IOException {
InputStream f = null;
InputStream b = null;
ZipInputStream z = null;
try {
f = new FileInputStream(fileName);
b = new BufferedInputStream(f);
z = new ZipInputStream(b);
doStuffWith(z);
}
finally {
if (z != null) { z.close(); }
if (b != null) { b.close(); }
if (f != null) { f.close(); }
}
}
</pre></code>
Or equivalently:
<code><pre>
public static void unzip(String fileName) throws IOException {
InputStream f = new FileInputStream(fileName);
try {
InputStream b = new BufferedInputStream(f);
try {
ZipInputStream z = new ZipInputStream(b);
try {
doStuffWith(z);
}
finally { z.close(); }
}
finally { b.close(); }
}
finally { f.close(); }
}
</pre></code>
Note that in the first method, you can really close the streams in any order; it doesn't matter. But for the second method, the order is dictated by the scope of the variables. Note also that with the second method, it's easy to refactor some of the nested blocks into separate methods, which can improve readability substantially if you need to put more complex logic into the method at different levels.
[This message has been edited by Jim Yingst (edited July 22, 2001).]
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!