简体   繁体   中英

Closing an input stream in Android (Java)

So. I'm trying to do some network stuff on Android. Inside my Async task, I'm doing:

InputStream streamOfDestiny = null;

try{
    // do some network stuff here...
}
finally{
    if(streamOfDestiny != null){
        streamOfDestiny.close(); // Build error here. Apparently, closing a stream can cause an IOException. Why this is the case, I do not know. But it is. And, since this is Java, I apparently need to care.
    }
}

So now I've got this IOException fouling everything up. I could do something like this:

InputStream streamOfDestiny = null;

try{
    // do some network stuff here...
}
finally{
    if(streamOfDestiny != null){
        try{
            streamOfDestiny.close();
        }
        catch(IOException e){
            // Hey look! I'm inside a catch block, inside a finally block!
        }
    }
}

But that just looks terrible. A try/catch block inside a finally block? How ugly! I could well leave it unclosed, but that seems like bad practice to me, and just feels wrong (I started the stream, I want to finish it). I could do this:

IOUtils.closeQuietly(streamOfDestiny);

But now I have to find org.apache.commons.io.IOUtils and somehow include that into my package. Too much work, plus increases my package size for something that I only need one function out of. Lame.

I could always write my own version of closeQuietly:

public static void closeStreamQuietly(InputStream streamToClose){
    try{
        streamToClose.close();
    }
    catch (IOException e){
        // ignore it....
    }
}

but that just seems like I'm re-inventing the wheel, which is almost always bad news - it feels like there ought to be some nice, elegant way of doing this that I'm completely missing here.

Any ideas folks?

I am not sure why are you terming your option-2 (try-catch block inside finally) or option-4 (creating a little util method) as ugly or extra work. This is normal and expected.

If you are writing any code inside finally then related exception handling should be done and this is the case here.

One exception handling you have already done(preventive) by putting a null check otherwise it could throw NullPointerException when streamOfDestiny is null.

Second exception handling is required to handle the exception scenarios of Stream closing, which could arise with the reasons such as Stream is not open , unavailable or it's not able to release the underline resources or scenarios like this etc.

Copy IOUtils code directly from the web:

http://grepcode.com/file/repo1.maven.org/maven2/commons-io/commons-io/1.4/org/apache/commons/io/IOUtils.java#IOUtils.closeQuietly%28java.io.InputStream%29

Also, get used to exception handling inside your finally blocks. This will not be the last time you see it.

There's no mystery. close() calls flush() in most implementations (see the Javadoc for FilterOutputStream ), and flush() can throw IOException, as it may perform I/O. Other possibilities are conceivable.

You should use try with resources.

try (InputStream streamOfDestiny = ...) {
    //Do you networking stuff
} catch (IOException ioe) {
    //Handle the exceptions
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM