声纳违规:“方法可能无法关闭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 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(); } } 

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

不好的做法 – 方法可能无法在exception时关闭流unZipElementsTo(String,String)可能无法关闭exception流

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

那就对了。 OutputStream.close()方法本身可以抛出exception。 如果发生这种情况,例如在finally{}块的第1行,则其他流将保持打开状态。

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

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

请注意,try-with-resources也适用于打开和关闭的多个对象,并且仍然保证对象将按其构造的相反顺序关闭。 相同的页面:

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

为避免在流关闭期间屏蔽exception和exception,通常建议在finally中“隐藏”任何ioexception。

要修复使用org.apache.commons.io.IOUtils.closeQuietly(…)或guava Closeables.html #closeQuietly(java.io.Closeable)在最后关闭

更多关于exception处理问题:
http://mestachs.wordpress.com/2012/10/10/through-the-eyes-of-sonar-exception-handling/

Interesting Posts