Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should an InputStream and an OutputStream be closed?

I'm using the following code to close an InputStream and an OutputStream from a connection to a server:

try {
        if (mInputStream != null) {
            mInputStream.close();
            mInputStream = null;
        }

        if (mOutputStream != null) {
            mOutputStream.close();
            mOutputStream = null;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

However, the streams are not closing, they are still alive. If I connect again there are two different InputStreams. No exception is being caught in the catch section.

What am I doing wrong?

like image 551
mooongcle Avatar asked Nov 05 '10 17:11

mooongcle


People also ask

How do I close OutputStream?

close() method closes this output stream and releases any system resources associated with this stream. The general contract of close is that it closes the output stream. A closed stream cannot perform output operations and cannot be reopened.

How do I close an InputStream?

close() method closes this stream and releases any system resources associated with the stream.

Does InputStream need to be closed?

You do need to close the input Stream, because the stream returned by the method you mention is actually FileInputStream or some other subclass of InputStream that holds a handle for a file. If you do not close this stream you have resource leakage.

Do I need to close OutputStream?

Don't close the OutputStream of a ServletResponse. You should only close Streams you've opened. See also: stackoverflow.com/questions/1829784/…


1 Answers

Edit: Added the Java 8 try-with-resources example at the bottom, since the language has evolved since originally posted.

If you are using Java 7 (or lower), there are two problems with your posted code:

  1. The .close() calls should be handled in a finally block. This way they will ALWAYS be closed, even if it fell into a catch block somewhere along the way.
  2. You need to handle EACH .close() call in its own try/catch block or you could leave one of them stranded open. If your attempt to close the input stream failed you would be skipping over the attempt to close the output stream.

You want something more like this:

    InputStream mInputStream = null;
    OutputStream mOutputStream = null;
    try {
        mInputStream = new FileInputStream("\\Path\\MyFileName1.txt");
        mOutputStream = new FileOutputStream("\\Path\\MyFileName2.txt");
        //... do stuff to your streams
    }
    catch(FileNotFoundException fnex) {
        //Handle the error... but the streams are still open!
    }
    finally {
        //close input
        if (mInputStream != null) {
            try {
                mInputStream.close();
            }
            catch(IOException ioex) {
                //Very bad things just happened... handle it
            }
        }
        //Close output
        if (mOutputStream != null) {
            try {
                mOutputStream.close();
            }
            catch(IOException ioex) {
                //Very bad things just happened... handle it
            }
        }
    }

If you are using Java 8+, you don't need any of the catch/finally noise. You can use the try-with-resources syntax and Java will close the resource for you whenever and however you leave the block:

    try(InputStream mInputStream = new FileInputStream("\\Path\\MyFileName1.txt")) {
        try(OutputStream mOutputStream = new FileOutputStream("\\Path\\MyFileName2.txt")) {
        //... do stuff to your streams
    }
}
like image 151
Skylar Sutton Avatar answered Sep 19 '22 10:09

Skylar Sutton