使用Apache commons-io IOUtils.close可以安全吗?

时间:2013-01-21 10:17:10

标签: java apache-commons apache-commons-io

这是代码吗

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

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

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

4 个答案:

答案 0 :(得分:37)

对于closeQuietly()

的javadoc,代码应如下所示
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()不是一般用途,而是直接在Closable上调用close()。它的预期用例是确保最终块内部的关闭 - 所有错误处理都必须在此之前完成。

这意味着,如果您想在调用close()flush()期间对异常做出反应,那么您将以正常方式处理它。在您的finally块中添加closeQuietly()只会确保关闭,例如当刷新失败并且在try-block中没有调用close时。

答案 1 :(得分:7)

只要您的应用程序不关心写入是否成功而没有错误,它是安全的。如果您的应用程序需要处理写入错误,则不安全,因为buffered data flushed on close可能会丢失并且吞下错误。

答案 2 :(得分:5)

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

你想要的是以下内容(在大多数情况下都是矫枉过正的)

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

} finally {
    // don't clobber a previous IOException
    IOUtils.closeQuietly(bw);
}

答案 3 :(得分:2)

是的,使用它是安全的,但仅适用于 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