【问题标题】:What is the best, and cleanest way to close a file in Java inside a finally block在finally块内关闭Java文件的最佳和最干净的方法是什么
【发布时间】:2021-04-12 05:42:30
【问题描述】:

我写了一个方法来关闭对文件的写入。 但是,一位高级开发人员建议我关闭 finally 块中的文件。

这是我的方法:

private static void writetoFiles(String error) {
    try {
        File file = new File("errorcode.txt");
        if (!file.exists()) {
            file.createNewFile();
    } else {
            FileWriter updateerrorcode = new FileWriter("errorcode.txt");
            updateerrorcode.write(error);
            updateerrorcode.close();
     }
    } catch (IOException e) {
    }
}

我在 stackoverflow 中阅读了很多答案,但对于像我这样的简单案例来说,所有答案似乎都太复杂了。 有什么建议我应该怎么做?

【问题讨论】:

  • 尝试资源:try (FileWriter updateerrorcode = new FileWriter("DatabaseErrorCode.txt")) { updateerrorcode.write(error); }
  • 是的,正是 Johannes Kuhn 所说的。使用try-with-resources,当资源超出范围时会自动关闭资源。

标签: java file-handling ioexception


【解决方案1】:

最简洁的方法是使用try-with-resources 语句,如下所示:

private static void writetoFiles(String error) throws IOException {
    //...

    try (FileWriter updateerrorcode = new FileWriter("errorcode.txt")) {
        updateerrorcode.write(error);
    }

    //...
}

如果方法无法处理,请不要在方法中捕获异常:

如果方法writetoFiles不能处理异常,它应该抛出同样的异常,以便调用方法可以适当地处理它。

【讨论】:

    【解决方案2】:

    使用try-with-resource statement

    private static void writetoFiles(String error) {
        try {
            File file = new File("errorcode.txt");
            if (!file.exists()) {
                file.createNewFile();
            } else {
                try (FileWriter updateerrorcode = new FileWriter("errorcode.txt")) {
                    updateerrorcode.write(error);
                }
            }
        } catch (IOException e) {
            // TODO: Handle error condition
        }
    }
    

    指出一个单独的问题...我认为您的示例中的逻辑是错误的。如果输出文件不存在,您的代码所做的就是创建该文件。只有当文件已经存在时,它才会将error 文本写入其中。我希望你想在这两种情况下写文本。如果这是真的,您根本不需要createNewFile 调用,因为FileWriter 类将在文件不存在时创建该文件。所以我认为你真正想要的是:

    private static void writetoFiles(String error) {
        try (FileWriter updateerrorcode = new FileWriter("errorcode.txt")) {
            updateerrorcode.write(error);
        } catch (IOException e) {
            // TODO: Handle error condition
        }
    }
    

    这将导致编写器在正常执行情况和错误抛出情况下都正确关闭。我假设在您的实际代码中,当 IOException 被捕获时,您会对其进行处理。我不知道你想在那里做什么,所以我不会提出任何建议。

    如果你想严格使用 finally 块,你可以这样做:

    FileWriter updateerrorcode = new FileWriter("errorcode.txt");
    try {
        updateerrorcode.write(error);
    }
    catch (IOException e) {
        // TODO: Handle error condition
    }
    finally {
        updateerrorcode.close();
    }
    

    在添加 try-with-resource 结构之前,这是 Java 早期版本中唯一的选项。在第二种方法中,您可能想从close() 捕获错误,但在我25 多年的Java 经验中,我不记得在文件失败时调用close()。我想如果您的目标卷上的磁盘空间不足并且close() 无法刷新流的写入缓冲区,您就会明白这一点。这个问题是较新方法的一个明显优势...关闭文件失败不会影响 write() 调用引发的异常的抛出/捕获。

    【讨论】:

    • @JohannesKuhn - 不想拿你的分数。只是认为这应该是一个真实的答案。如果您以自己的名义复制/粘贴此答案,我将删除我的副本。
    • 真的是try-with-resource语句吗?
    • finally 块是否可以访问在 try 资源下创建的变量?我怀疑。
    • 3 件事,try-with-resource 是这样的:tr​​y (FileWriter updateerrorcode = new FileWriter("DatabaseErrorCode.txt"))... finally 块中的异常呢?最后一个变量将如何在 finally 块中看到第一个 sn-p。
    • 您的答案包括问题中代码的空 catch 块。我认为应该删除或更改以引发运行时异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 2010-09-08
    • 2020-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多