在Java中,关闭父输入流也会关闭其子节点吗?

时间:2012-01-24 09:14:09

标签: java

FileInputStream fis = new FileInputStream(gzipFile);
GZIPInputStream gis = new GZIPInputStream(fis);
gis.close();
fis.close();

fis.close()是否必要?虽然我正在运行此代码,但似乎没有任何错误。

3 个答案:

答案 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,该成员通过构造函数设置。 (另一个假设是GZIPInputStreamInflaterInputStream将构造函数参数传递给它们的超类,但这很可能确实存在。)

所以FilterInputStream清楚地告诉你它将关闭你提供给构造函数的流。其他人打电话super.close()的几率非常高,即使他们的记录很差,所以是的,为你关闭它,你不应该这样做你自己。但是有一些假设涉及。

答案 2 :(得分:2)

是的,确实如此。 javadoc说:

  

关闭此输入流并释放所有关联的系统资源   与流。

包装的流肯定是这样的系统资源。

此外,GZIPInputStream FilterInputStream,FilterInputStream javadoc说:

  

关闭此输入流并释放所有关联的系统资源   与流。此方法只执行in.close()。