我看到了这段代码,并想知道为什么在in.close()
中完成finally block
。 try-with resources
的要点是它closes
正确resources
。
File file = new File(FILE_NAME);
FileInputStream in = null;
try (in = new FileInputStream(file)){
//do something
} catch (final FileNotFoundException e) {
log.log(Level.WARNING, "file not found, " + file.getAbsolutePath(), e);
} catch (final IOException e) {
log.log(Level.WARNING, "cannot access the file for reading", e);
} finally {
if (in != null){
try {
in.close();
} catch (final IOException e) {
log.log(Level.WARNING, "Attempt to close file failed.", e);
}
}
}
是否存在可以打开文件但无法使用Java中的try-with-resources关闭的情况?
答案 0 :(得分:3)
示例中的finally
块是多余的。 try-with-resources语句基本上是这样做的(但是更容易出错!)。因为它在try-with-resources语句尝试关闭资源后执行,finally
块本质上是一个noop(可能有第二次尝试在第一次失败后成功关闭资源 - 但是如果这甚至是可能的,这是一个可以忽略的边缘情况,当然也是非确定性的。)
请注意,catch
块对比非常重要。关闭资源的尝试将在catch
块被激活之前发生,导致可能发生多个异常。这可以通过使用抑制异常来解决。因此,如果使用资源失败,仍然会尝试正确关闭它(通常也会失败)和 catch
块将收到第一个(最可能是根)原因,而不是在关闭隐藏第一个错误时抛出的异常。
有关更多信息,请参阅官方documentation!
答案 1 :(得分:1)
这不是文件所独有的,它通常与I / O一起发生。
Java API规范如果发生“发生I / O错误”,InputStream的close()方法可能会启动异常
所以是的,它可能发生,这种行为产生了有趣(或不那么有趣)的try-catch-finally-try-catch块。
答案 2 :(得分:1)
我会使用一些可移动存储(例如USB记忆棒)进行简单的测试:
只需编写一个程序,使用USB记忆棒中的文件打开FileInputStream
,然后提示“请删除存储设备”,等待< Enter>然后尝试in.close()
。我敢打赌会抛出一些IOException
。
答案 3 :(得分:1)
是的,这可能发生。 close()
的方法签名确实抛出IOException
,因此应该为这种可能性做好准备。
通常,catch块将被移动到方法之外,这使得处理它看起来更容易和更清洁。例如:
public static void main(String[] args)
{
try {
readFile(new File("MyFile.txt"));
} catch (IOException e) {
/* handle the exception */
}
}
private static void readFile(File file) throws IOException
{
FileInputStream in = null;
try {
in = new FileInputStream(file);
/* Read the file. THIS MIGHT FAIL! */
} finally {
if (in != null) /* Check this because new FileInputStream() could have failed */
in.close(); /* If this throws and exception, it will be handled by main() */
}
}