编辑:忘记提到我正在使用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
)?。
欢迎任何意见。
您可以进行
try (InputStream s1 = new FileInputStream("file");
InputStream s2 = new BufferedInputStream(s1);
ZipInputStream zin = new ZipInputStream(s2)) {
// ...
} catch (IOException e) {
// ...
}
进一步阅读:Java™教程:资源尝试语句。
可以这样做:
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();
}
您还可以在需要的地方添加错误缓存。
首先让我们看看您有什么以及它可能出现的问题:
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.)new FileInputStream()抛出,则不会分配zin。在这种情况下没有什么可关闭的。好的。
b.)新的BufferedInputStream()throws(可能是OutOfMemoryError),zin未分配。泄漏的FileInputStream()。糟糕
c.)新的ZipInputStream()抛出,则不会分配zin。BufferedInputStream和FileInputStream。关闭任何一个都足够了。糟糕
每当你将一股流包裹到另一股流中时,你就面临着包裹的流泄漏的危险。你需要有一个参考,并关闭它的某个地方。
除此之外,一种可行的方法是可变地声明单个InputStream,以保持最后一个创建流(或者换句话说,嵌套流中最外层的流):
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
是与创建的所有流兼容的类型赋值。
是的,除非在异常处理中进行级联检查,否则新的ZipInputStream()或新的BufferedInputStream(
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的包装器,因此发生异常的概率相当低。如果有的话,一旦您开始读取和处理数据,则最有可能发生异常。在这种情况下,zin被创建,一个zin.close()就足够了。