编辑:忘了提我正在使用java 6
我想知道如何关闭java中的资源。
看,我总是像这样初始化流:
ZipInputStream zin = null;
try {
zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
// Work with the entries...
// Exception handling
} finally {
if (zin!=null) { try {zin.close();} catch (IOException ignored) {} }
}
但是,如果在new ZipInputStream(...)
中抛出异常,那么new BufferedInputStream
中打开的流量会不会泄漏FileInputStream
吗?
如果是,那么确保资源关闭的最有效方法是什么?,我是否必须保留对每个new ...Stream
的引用并在finally
块中关闭它们?或者最终的流(在这种情况下是ZipInputStream
)是否应该以其他方式实例化?。
欢迎任何评论。
答案 0 :(得分:3)
你可以做到
try (InputStream s1 = new FileInputStream("file");
InputStream s2 = new BufferedInputStream(s1);
ZipInputStream zin = new ZipInputStream(s2)) {
// ...
} catch (IOException e) {
// ...
}
进一步阅读:The Java™ Tutorials: The try-with-resources Statement。
答案 1 :(得分:1)
可以这样做:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
try {
ZipInputStream zin = new ZipInputStream(bis);
try {
zin = ;
// Work with the entries...
// Exception handling
} finally {
zin.close();
}
} finally {
bis.close();
}
您可以在任意位置添加错误缓存。
答案 2 :(得分:0)
是的,新的ZipInputStream()或新的BufferedInputStream()中的异常会泄漏封闭的Streams,除非您在异常处理中进行级联检查:
FileInputStream fin = null;
BufferedInputStream bin = null;
ZipInputStream zin = null;
try {
fin = new FileInputStream(file);
bin = new BufferedInputStream(fin)
zin = new ZipInputStream(bin);
// Work with the entries...
// Exception handling
} finally {
try {
if (zin!=null) {
zin.close();
} else if (bin != null) {
bin.close();
} else if (fin != null) {
fin.close();
}
} catch (Exception e) {
// ignore
}
}
但是,由于BufferedInputStream和ZipInputStream仅仅是FileInputStream的包装器,因此Exception的概率相当低。如果有的话,一旦开始阅读和处理数据,最有可能发生异常。在这种情况下,创建了zin,并且zin.close()就足够了。
答案 3 :(得分:0)
首先让我们来看看你有什么以及它可能出现什么问题:
try {
zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(file)));
// Work with the entries...
// Exception handling
} finally {
if (zin!=null) { try {zin.close();} catch (IOException ignored) {} }
}
a。)抛出新的FileInputStream(),不会分配zin。在这种情况下无需关闭。好吧。
b。)新的BufferedInputStream()抛出(可能是OutOfMemoryError),未分配zin。泄露FileInputStream()。坏。
c。)抛出新的ZipInputStream(),不会分配zin。要关闭BufferedInputStream和FileInputStream。关闭任何一个就足够了。坏。
每当你将一个流包装到另一个流中时,你就有可能泄漏你正在包装的流。你需要引用它并在某处关闭它。
一种可行的方法是首先声明一个InputStream可变地保存最后一个create 流(或者换句话说,最外面的嵌套流):
InputStream input = null;
try {
input = new FileInputStream(...);
input = new BufferedInputStream(input);
input = new ZipInputStream(input);
ZipInputStream zin = (ZipInputStream) input;
// work here
} finally {
if (input != null)
try { input.close(); } catch (IOException ignored) {}
}
这是有效的,因为如果任何new *Stream()
抛出,变量input
仍然跟踪之前创建的流。从input
到ZipInputStream的丑陋演员是必要的,因为您必须声明input
是与所有创建的流兼容的类型赋值。