【问题标题】:Regarding java file closing关于java文件关闭
【发布时间】:2010-03-05 02:31:23
【问题描述】:

我注意到在一个 java 程序中,下面一行用于打开一个文件并处理它

BufferedReader inp = new BufferedReader(new FileReader(inputFile));

在java程序中,inp在退出程序之前没有关闭,下面的行丢失了

if (inp != null)
    try {
       inp.close();
    } catch (IOException logOrIgnore) {}

程序在很多地方都有退出,但他们没有关闭文件。我需要把这条线放在任何地方吗?如果我在程序退出时不关闭文件,这将是一个问题。 垃圾收集器会关闭文件吗?

【问题讨论】:

  • BufferedReader 是传递给其他方法还是仅在一个位置使用?
  • “程序在很多地方都有退出”是什么意思?程序是否使用 System.exit() 终止?如果是这样,那么 try/finally 方法将不起作用。
  • 在相关说明中,我有时真的希望 Java 有 using(类似于 C#)。它允许以更少的代码混乱进行确定性处理,并鼓励正确的事情。

标签: java string


【解决方案1】:

你应该使用try/finally:

Reader inp = new BufferedReader(new FileReader(inputFile));
try {
    // Do stuff with "inp"
} finally {
    IOUtils.closeQuietly(inp);
}

IOUtils 来自Apache Commons IO。它的closeQuietly 方法就像你上面的代码sn-p:它调用close,并忽略任何抛出的异常。

【讨论】:

    【解决方案2】:

    垃圾收集器不会关闭文件。如果你知道你的程序不会长时间运行或打开很多文件,你可以在不关闭文件的情况下逃脱。但否则你需要手动关闭它。

    【讨论】:

    • function() { BufferedReader inp = new BufferedReader(new FileReader(inputFile));由于它是在对象函数内部定义的,它不会在函数退出后自动销毁吗?如果我不关闭它会成为问题吗?
    • 垃圾收集器确实关闭文件,但不能保证它会执行。当进程退出时,操作系统也会关闭文件。对于输入文件,这已经足够了。对于BufferedOutputStream、BufferedWriter、ObjectOutputStream、PrintStream、PrintWriter等应用空间有缓冲区的输出文件,则不然。
    • @EJP:FileReader 或 BufferedReader 的 javadoc 中没有任何内容表明它将自动关闭。他们都有一个明确的 close() 方法。它们都从 Object 继承 finalize(),所以我看不出当对象被 GC 时会发生任何特定于读者的事情。 (您当然是正确的,操作系统会在进程退出时关闭文件。)
    【解决方案3】:

    听起来您正在使用BufferedReader 而不返回它被声明的上下文(可能是一个实例变量?)。在这种情况下,您必须在每次可能退出应用程序时手动关闭它。您不能依赖垃圾收集器为您执行此操作。

    【讨论】:

    • function() { BufferedReader inp = new BufferedReader(new FileReader(inputFile));由于它是在对象函数内部定义的,它不会在函数退出后自动销毁吗?如果我不关闭它会成为问题吗?
    • @arav:它最终会收集垃圾(可能很快,但不能保证及时性),但是,这不会在函数退出时立即发生。 try/finally 方法允许文件的关闭恰好在您期望它发生的时候发生(“确定性处置”)。
    • @arav:至于如果你不明确关闭它是否是一个问题,如果你在垃圾收集器最终确定你的读者之前调用该函数太多次,那么你将用完可用文件描述符,并且不会进一步打开成功(直到某些现有文件描述符被关闭)。
    猜你喜欢
    • 2010-09-12
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多