声纳违规:"Method may fail to close stream on exception"



我有这个方法:

 private void unZipElementsTo(String inputZipFileName, String destPath) throws FileNotFoundException, IOException {
        OutputStream out = null;
        InputStream in = null;
        ZipFile zf = null;
        try {
            zf = new ZipFile(inputZipFileName);
            for (Enumeration<? extends ZipEntry> em = zf.entries(); em.hasMoreElements();) {
                ZipEntry entry = em.nextElement();
                String targetFile = destPath + FILE_SEPARATOR + entry.toString().replace("/", FILE_SEPARATOR);
                File temp = new File(targetFile);
                if (!temp.getParentFile().exists()) {
                    temp.getParentFile().mkdirs();
                }
                in = zf.getInputStream(entry);
                out = new FileOutputStream(targetFile);
                byte[] buf = new byte[4096];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.flush();
                out.close();
                in.close();
            }
        }
        finally
        {
            if (out!=null) out.close();
            if (zf!=null) zf.close();
            if (in!=null) in.close();
        }
    }

对于这种方法,声纳给我这个违规:

错误做法-方法可能无法在出现异常时关闭流unZipElementsTo(String,String)可能无法在异常上关闭流

但是,我没有看到任何违规行为。也许,这只是一个假阳性?

没错。OutputStream.close()方法本身可以引发异常。如果发生这种情况,例如在finally{}块的第一行,则其他流将保持打开状态。

如果finally块中的out.close()zf.close()抛出异常,则不会执行其他关闭。

或者,如果您使用的是Java7或更好的版本,您可以使用新的try-with-resources机制,它可以为您处理关闭。请参阅:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html了解有关此新机制的详细信息。

请注意,try-with-resources还可以处理打开和关闭的多个对象,并且仍然可以保证对象将按其构造的相反顺序关闭。引用同一页:

请注意,资源的close方法的调用顺序与其创建顺序相反。

为了避免在流关闭期间用异常屏蔽异常通常建议在finally中"隐藏"任何io异常。

要修复此问题,请使用org.apache.commons.io.IOUtils.closeQuietly(…)或番石榴Closeables.html#closeQuietly(java.io.Closeable)在最终关闭的中

有关异常处理问题的详细信息:
http://mestachs.wordpress.com/2012/10/10/through-the-eyes-of-sonar-exception-handling/

相关内容

最新更新