38

这是代码吗

    BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
    try {
        bw.write("test");
    } finally {
        IOUtils.closeQuietly(bw);
    }

安全与否?据我了解,当我们关闭 BufferedWriter 时,它会将其缓冲区刷新到底层流,并且可能由于错误而失败。但是 IOUtils.closeQuietly API 说任何异常都会被忽略。

由于 IOUtils.closeQuietly,数据丢失是否可能会被忽视?

4

4 回答 4

42

关于 javadoc 的代码应如下所示closeQuietly()

BufferedWriter bw = null;

try {
    bw = new BufferedWriter(new FileWriter("test.txt"));
    bw.write("test");
    bw.flush(); // you can omit this if you don't care about errors while flushing
    bw.close(); // you can omit this if you don't care about errors while closing
} catch (IOException e) {
    // error handling (e.g. on flushing)
} finally {
    IOUtils.closeQuietly(bw);
}

closeQuietly()不打算用于一般用途,而不是close()直接调用 Closable。它的预期用例是确保在 finally 块内关闭 - 您需要在此之前完成所有错误处理。

这意味着,如果您想在调用过程中对异常做出反应,close()或者flush()您必须以正常方式处理它。添加closeQuietly()你的finally块只是确保关闭,例如当刷新失败并且在try块中没有调用close时。

于 2013-01-21T10:57:53.100 回答
8

只要您的应用程序不关心写入是否成功且没有错误,它就是安全的。如果您的应用程序需要处理写入错误,这是不安全的,因为在关闭时刷新的缓冲数据可能会丢失并且错误会被吞没。

于 2013-01-21T10:46:24.177 回答
6

是的,使用它是安全的,但仅适用于Java6及更低版本。从Java7 开始,您应该使用try-with-resource

它将消除您拥有的大部分样板代码以及使用IOUtils.closeQuietly.

现在,你举个例子:

    BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"));
    try {
        bw.write("test");
    } finally {
        IOUtils.closeQuietly(bw);
    }

可以写成:

   try (BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"))) {
       bw.write("test");
   }

需要注意的是,为了使用 try-with-resource 方法,您的资源需要实现 Java 7 中引入的名为 java.lang.AutoCloseable 的新接口。

此外,您可以在 try-with-resource 块中包含许多资源,只需将它们用;

   try (
       BufferedWriter bw1 = new BufferedWriter(new FileWriter("test1.txt"));
       BufferedWriter bw2 = new BufferedWriter(new FileWriter("test2.txt"))
   ) {
       // Do something useful with those 2 buffers!
   }   // bw1 and bw2 will be closed in any case
于 2018-03-13T08:42:46.823 回答
5

这在理论上是可能的,但我不能说我见过 close() 失败。通常fail fast意味着之前的IO操作比如打开文件会先失败。您可以编写一个不忽略 IOExceptions 的关闭,但如果它是 try/catch 块中的某些内容失败,这可能会破坏异常的真正原因。

你想要的是类似以下的东西(在大多数情况下这是矫枉过正的)

try {
    // write to bw.
    bw.close(); // throw IOException if an error occurs.

} finally {
    // don't clobber a previous IOException
    IOUtils.closeQuietly(bw);
}
于 2013-01-21T10:22:22.500 回答