我应该在哪里放置close()方法?

时间:2013-12-19 14:40:34

标签: java exception file-io

在以下代码中,关闭位于何处?它应该在try子句中还是在最后?如果它是最后的,它应该用另一个try-catch包围吗?感谢。

PrintWriter out = null;
try {
    out = new PrintWriter(
            new BufferedWriter(
                new FileWriter("out.txt", true)));
    out.println("the text");
} catch (IOException e) {
    System.err.println(e);
} finally {
    if (out != null) {
        out.close();
    }
}

3 个答案:

答案 0 :(得分:4)

请参阅try-with-resources的文档。如果你至少使用Java 7,那么就有一个很好的语法。否则,finally块是合适的,因为它应该在正常和特殊情况下都关闭。

答案 1 :(得分:3)

把它放在finally块中。

因为你应该在任何一种情况下关闭Writer(例外或无异常)。

答案 2 :(得分:0)

要正确处理close,应该确保无论主线代码中是否发生异常都会调用它,但是还应该确保在{1}}之后调用close主线然后抛出一个异常本身,它不会导致主线异常被丢弃;取决于各种因素,包括对象是否打开以进行读取或写入,可能需要让主线异常渗透(可能封装有关关闭失败的信息),记录或封装主线异常但具有close失败渗透,或抛出“双重错误”异常,封装了其他两个异常。

Java 7的try-with-resources功能为许多场景提供了非常好的行为:如果try中发生异常而close中发生异常,则后一个异常会被添加到抑制列表中异常(异常处理代码应该寻找)。如果一个方法应该从无线传感器中获取数据并将其写入文件,并且如果调用者希望在传感器出现故障的情况下该文件将保存尽可能多的信息,那么就无法关闭文件可能比传感器故障更重要[如果传感器例如只包括“返回最旧的项目”和“删除最旧的项目”命令,然后如果文件正确关闭传感器通信期间的异常将意味着传感器中不再存在的任何数据将在文件中。如果文件没有正确关闭,那就意味着可能存在永久性数据丢失,应该告诉某人。

处理“传感器捕获”场景的代码最终会变得有点棘手:传感器读取逻辑将放置在try块中,finally将捕获变量的任何异常。然后,finally块必须使用自己的try块进行关闭;如果在那里发生异常,则抛出一个自定义writeFileCloseFailure异常,该异常封装try块中的异常(如果有)和close中的异常;否则,从try块重新抛出异常(如果有的话)。请注意,由于ioException可能表示无法从传感器获取数据(有些预期和可容忍)或无法写入文件(非常糟糕),因此包装另一个异常类型将允许调用者区分这些条件