In Java, closing a parent input stream also closes its child?

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

Is fis.close () required? Although I run this code and see no errors.

+6
source share
3 answers

You should see the implementation of 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; } } 

If you look at the constructor for GZIPInputStream , it looks like this:

 /** * 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); } 

Observe the in variable. Notice how this is passed to the super class, which in this case is InflaterInputStream .

Now, if we look at the implementation of the InflaterInputStream.close() method, we will find this:

 /** * 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; } } 

It is clear that in.close() called. Thus, the completed (decorated) FileInputStream also closes when GZIPInputStream.close() called. Thich makes calling fis.close() redundant.

+7
source

This is one of those things that people should clearly document. Unfortunately, GZIPInputStream overrides close in its parent class and does not document what it is doing (poor documentation). But the chances are pretty high (without even looking at the code) that it will eventually call super.close() (and indeed, we can see from adarshr's answer what it does, although you should never assume that the implementation will not change) . If so, then we will look at the documents for the parent class ( InflaterInputStream ). Unfortunately, he does the same, redefines without documenting. But suppose he also calls super.close() at some point. Looking at his parent class ( FilterInputStream ) docs, he explicitly says it executes close on the in element that is set through the constructor. (A separate assumption is that GZIPInputStream and InflaterInputStream pass the constructor argument to their superclasses, but this is very likely.)

So FilterInputStream clearly tells you that it is going to close the stream that you provided to the constructor. The chances are pretty high, others are going to call super.close() , although they are poorly documented, so yes, this should close it for you, and you won’t have to do it yourself. But there are some assumptions.

+2
source

Yes Yes. The javadoc says:

Closes this input stream and releases the associated system resources with the stream.

And the wrapped thread is definitely such a system resource.

In addition, GZIPInputStream is a FilterInputStream, and the javadoc FilterInputStream says:

Closes this input stream and releases the associated system resources with the stream. This method simply executes in.close ().

+2
source

Source: https://habr.com/ru/post/906742/


All Articles