Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FindBugs:" may fail to close stream ", how to solve it?

The follow code is marked as erroneous by FindBugs. FindBugs says that "This method may fail to clean up (close, dispose of) a stream, database object, or other resource requiring an explicit cleanup operation." The error is marked on the line output = new FileOutputStream (localFile);

But we have already added try/finally to the block.

inputStream   input =null;
OutputStream output =null;
try {
    input = zipFile.getInputStream(entry);
    File localFile = new File(unzipFile.getAbsolutePath()
            + File.separator + entryName);
    output = new FileOutputStream (localFile);  // BUG MARKED HERE
    byte[] buffer = new byte[1024 * 8];
    int readLen = 0;
    while ((readLen = input.read(buffer, 0, 1024 * 8)) != -1) {
        output.write(buffer, 0, readLen);
    }
    output.flush();
    output.close();
    input.close();

} finally {
    if(output!=null) {
        output.flush();
        output.close();
    }
    if(input!=null) {
        input.close();
    }
}
like image 706
smart Avatar asked Dec 17 '13 07:12

smart


1 Answers

Remove all close() calls (and the last flush() call) located in your try block since that code will be unreached for in case of errors. That's where the warning comes from. Findbugs is triggered there to believe you tried to handle them within the try/catch block.

Also in your finally it's better to wrap in another try catch block so that you can handle errors there and if output closing fails you could still continue with closing input.

                   // your code here
                   output.write(buffer, 0, readLen);
                   // removed these since findbug complains about this
                }
            } finally {
                // TODO some more try catching here so that if output closing 
                // fails you can still try to close second one and log the errors!
                if(output!=null)
                {
                    output.flush();
                    output.close();
                }
                if(input!=null)
                {
                    input.close();
                }
            }

Also for java 7 and up there are better solutions. See http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html (thanks to @user2864740 for the link).

like image 91
hcpl Avatar answered Nov 05 '22 10:11

hcpl