在Java中编写文件时是否需要在finally中调用close()?

时间:2016-05-04 20:47:51

标签: java android

有几个examples人们在写入文件时会在close()块中调用finally,如下所示:

OutputStream out = null;
try {
    out = new FileOutputStream(file);
    out.write(data);
    out.close();
}
catch (IOException e) {
    Log.e("Exception", "File write failed: " + e.toString());
} finally {
    try {
        if (out != null) {
            out.close();
        }
    } catch (IOException e) {
        Log.e("Exception", "File write failed: " + e.toString());
    }
}

但是有many more个例子,包括the official Android docs他们不会这样做:

try {
    OutputStream out = new FileOutputStream(file);
    out.write(data);
    out.close();
}
catch (IOException e) {
    Log.e("Exception", "File write failed: " + e.toString());
}

鉴于第二个示例要短得多,是否真的有必要在close()中调用finally,如上所示,还是有一些机制会自动清理文件句柄?

4 个答案:

答案 0 :(得分:6)

每种情况都有点不同,但最好总是在finally块中关闭或者使用java的try with resources语法,这实际上是相同的。

通过不关闭finally块而运行的风险是,在捕获到catch之后,您最终得到一个未关闭的流对象。此外,如果您的流被缓冲,您可能需要最后关闭以刷新缓冲区以确保写入完全完成。在没有最终结束的情况下完成可能是一个严重的错误。

答案 1 :(得分:2)

不关闭文件可能意味着流内容不会及时刷新。在代码正常完成且不抛出异常的情况下,这是一个问题。

如果你没有关闭FileOutputStream,那么它的finalize方法将尝试关闭它。但是,finalize不会立即被调用,根本不能保证被调用,请参阅this question。最好不要依赖于此。

如果JDK7的try-with-resources是一个选项,那么使用它:

try (OutputStream out = new FileOutputStream(file);) {
    out.write(data);
}

否则,对于JDK6,请确保关闭时抛出的异常不能屏蔽try块中抛出的任何异常:

OutputStream out = new FileOutputStream(file);
try {
    out.write(data);
} finally {
    try {
        out.close();
    } catch (IOException e) {
        Log.e("Exception", "File write failed: " + e.toString());
    }
}

它可能很冗长但确保文件关闭。

答案 2 :(得分:1)

是的,确实如此。除非你让其他人为你管理。

一些解决方案:

答案 3 :(得分:0)

在写入或读取文件时始终关闭是非常重要的,因为如果您不关闭作者或读者。除非您关闭阅读器,否则您将无法写入文件,反之亦然。

此外,如果您不关闭,可能会导致内存泄漏。永远记得关闭你打开的任何东西。关闭它并不会造成伤害,如果有的话,它会使你的代码更有效率。