javastreamtry-catchinputstreamtry-with-resources

Java close both Connection and InputStream with try statement


Should I close HttpUrlConnection and InputStream in this case? Only closing the connection will close the stream also? I feel that it's a bad practice but don't know exactly why.

Closing both:

HttpURLConnection con = (HttpURLConnection) obj.openConnection();
try (AutoCloseable ac = con::disconnect) {
    int responseCode = con.getResponseCode();
    try (InputStream ins = responseCode >= 400 ? con.getErrorStream() : con.getInputStream();
        BufferedReader in = new BufferedReader(new InputStreamReader(ins))) {
        // receive response
    }
}

Closing Connection only:

HttpURLConnection con = (HttpURLConnection) obj.openConnection();
try (AutoCloseable ac = con::disconnect) {
    int responseCode = con.getResponseCode();
    BufferedReader in = new BufferedReader(new InputStreamReader(ins)))
    // ins will close automatically when con closes?
    // receive response
}

Solution

  • When you disconnect the HttpURLConnection object, it MAY also close any InputStream or OutputStream that it has opened.

    HttpURLConnection.disconnect() method description:

    Calling the disconnect() method may close the underlying socket if a persistent connection is otherwise idle at that time.

    You can read more here.

    In turn, Socket.close() method description:

    Closing this socket will also close the socket's InputStream and OutputStream. If this socket has an associated channel then the channel is closed as well.

    You can read more here.

    But pay attention that "disconnecting" HttpURLConnection doesn’t mandatory close the Socket. It have been already discussed quite well in that thread:

    (When keepAlive == true) If client called HttpURLConnection.getInputSteam().close(), the later call to HttpURLConnection.disconnect() will NOT close the Socket. i.e. The Socket is reused (cached) If client does not call close(), call disconnect() will close the InputStream and close the Socket. So in order to reuse the Socket, just call InputStream.close(). Do not call HttpURLConnection.disconnect().

    On the other hand, in the official oracle tutorials they suggest to close InputStream explicitly in order to be sure that resources don’t leak.