Search code examples
javafilestreamresource-leak

How to solve failure to close a FileStream


I have closed file steam in try/finally, but code analysis warns me:

  • Possible failure to close a FileOutputStream
  • Possible failure to close a PrintWriter
  • Possible failure to close an OutputStreamWriter

How can failure happen? How can I ensure the FileStream is closed?

public void writeFile(String filepath)
{
    BufferedWriter bw = null;
    PrintWriter pw = null;
    try {
        File file = new File(filepath);
        bfw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
        pw = new PrintWriter(bfw);

     //do something

    }catch(Exception e){
        e.printStackTrace();
    }
    finally{
        try{
            bfw.close();
            pw.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

Solution

  • How can failure happen?

    See your finally block:

    finally{
        try{
            bfw.close();   <== exception occured here
            pw.close();    <== this is not execute
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    

    What if an exception occurs in bfw.close()? pw.close() will never execute. And this leads to a resource leak.

    How can I ensure the FileStream is closed?

    Someone already pointed out using try/catch/finally inside finally. But if you don't like to see so many try catch finally I would suggest you to use a library like Apache Commons IO.

    Solution:

    try {
    
       ........
    } finally {
        IOUtils.closeQuietly(bfw);
        IOUtils.closeQuietly(pw);
    }
    

    And yes, you always have try-with-resources if using Java 7 or above.