关闭文件失败了吗?

时间:2014-02-04 22:11:32

标签: java exception finally try-with-resources

我看到了这段代码,并想知道为什么在in.close()中完成finally blocktry-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关闭的情况?

4 个答案:

答案 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() */
    }
}