FileInputStream fis = new FileInputStream(gzipFile);
GZIPInputStream gis = new GZIPInputStream(fis);
gis.close();
fis.close();
fis.close()是否必要?虽然我正在运行此代码,但似乎没有任何错误。
答案 0 :(得分:8)
您应该看到GZIPInputStream.close()
。
/**
* Closes this input stream and releases any system resources associated
* with the stream.
* @exception IOException if an I/O error has occurred
*/
public void close() throws IOException {
if (!closed) {
super.close();
eos = true;
closed = true;
}
}
如果你看一下GZIPInputStream
的构造函数,它看起来像这样:
/**
* Creates a new input stream with the specified buffer size.
* @param in the input stream
* @param size the input buffer size
* @exception IOException if an I/O error has occurred
* @exception IllegalArgumentException if size is <= 0
*/
public GZIPInputStream(InputStream in, int size) throws IOException {
super(in, new Inflater(true), size);
usesDefaultInflater = true;
readHeader(in);
}
观察变量in
。注意在这种情况下如何将它传递给超级类InflaterInputStream
。
现在,如果我们看一下InflaterInputStream.close()
方法的实现,我们会发现:
/**
* Closes this input stream and releases any system resources associated
* with the stream.
* @exception IOException if an I/O error has occurred
*/
public void close() throws IOException {
if (!closed) {
if (usesDefaultInflater)
inf.end();
in.close();
closed = true;
}
}
显然,in.close()
正在被调用。所以包裹(装饰)FileInputStream
也会在调用GZIPInputStream.close()
时关闭。这使得调用fis.close()
变得多余。
答案 1 :(得分:2)
这是人们需要清楚记录的事情之一。不幸的是,GZIPInputStream
会覆盖其父类中的close
,并且不会记录它的作用(文档很差)。但是可能性很高(甚至没有查看代码)它最终会调用super.close()
(事实上我们可以从adarshr的答案中看到它确实如此,尽管你永远不应该认为实现不会改变)。如果是这样,那么我们查看父类(InflaterInputStream
)的文档。不幸的是,它完全相同的事情,覆盖没有记录。但是假设它在某个时刻也会调用super.close()
。查看其父类(FilterInputStream
)文档,explicitly says它在close
成员上执行in
,该成员通过构造函数设置。 (另一个假设是GZIPInputStream
和InflaterInputStream
将构造函数参数传递给它们的超类,但这很可能确实存在。)
所以FilterInputStream
清楚地告诉你它将关闭你提供给构造函数的流。其他人打电话super.close()
的几率非常高,即使他们的记录很差,所以是的,应为你关闭它,你不应该这样做你自己。但是有一些假设涉及。
答案 2 :(得分:2)
是的,确实如此。 javadoc说:
关闭此输入流并释放所有关联的系统资源 与流。
包装的流肯定是这样的系统资源。
此外,GZIPInputStream 是 FilterInputStream,FilterInputStream javadoc说:
关闭此输入流并释放所有关联的系统资源 与流。此方法只执行in.close()。