我有这个方法:
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)可能无法在异常
上关闭流
但是,我没有看到任何违规行为。也许,这只是假阳性?
答案 0 :(得分:8)
没错。
OutputStream.close()
方法本身可以抛出异常。
如果发生这种情况,在finally{}
区块的第一行,然后其他流将保持打开状态。
答案 1 :(得分:2)
如果out.close()
块中的zf.close()
或finally
抛出异常,则其他关闭将不会执行。
答案 2 :(得分:2)
或者,如果您使用的是Java 7或更高版本,则可以使用新的try-with-resources机制来处理关闭。有关此新机制的详细信息,请参阅:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html。
请注意,try-with-resources也适用于打开和关闭的多个对象,并且仍然保证对象将按其构造的相反顺序关闭。同一页:
请注意,资源的close方法按其创建的相反顺序调用。
答案 3 :(得分:0)
避免在关闭流时屏蔽异常并发生异常 通常建议在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/