2

我看到了这段代码,想知道为什么in.close()finally block. 的要点try-with resources是它closesresources正确的。

  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

4 回答 4

4

您示例中的finally块是多余的。try-with-resources 语句基本上做同样的事情(但更不容易出错!)。由于它是在 try-with-resources 语句尝试关闭资源之后执行的,因此该finally块本质上是一个 noop(可能在第一次失败后第二次尝试关闭资源成功 - 但如果这甚至可能,这是一个可以忽略不计的边缘情况,当然是不确定的)。

请注意,catch相反的块很重要。关闭资源的尝试将在catch块被激活之前发生,从而导致发生多个异常的可能性。这可以通过使用抑制的异常来解决。因此,如果使用资源失败,仍然会尝试正确关闭它(这通常也会失败),并且 catch块将收到第一个(最有可能的根本)原因,而不是在关闭隐藏第一个错误时抛出异常。

更多信息请查看官方文档

于 2014-02-04T22:27:41.167 回答
1

这不是文件独有的,它通常发生在 I/O 中。

Java API 规定 InputStream 的 close() 方法可能会在“发生 I/O 错误”时引发异常

所以是的,它可能会发生,这种行为会产生有趣(或不那么有趣)的 try-catch-finally-try-catch 块。

于 2014-02-04T22:22:47.783 回答
1

我会用一些可移动存储(例如 U 盘)做一个简单的测试:

只需编写一个程序,FileInputStream从 U 盘打开一个文件,然后提示“请移除存储设备”,等待 <Enter> 然后尝试in.close(). 我敢打赌,有些IOException人会被扔掉。

于 2014-02-04T22:22:56.037 回答
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() */
    }
}
于 2014-02-04T22:24:39.613 回答