请注意,以下内容仅适用于 Java 6 及更早版本。对于 Java 7 及更高版本,您应该切换到使用 try-with-resources ...如其他答案中所述。
如果您尝试在源代码(在 Java 6 或更早版本中)捕获并报告所有异常,更好的解决方案是:
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(shapes);
oos.flush();
} catch (FileNotFoundException ex) {
// complain to user
} catch (IOException ex) {
// notify user
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException ex) {
// ignore ... any significant errors should already have been
// reported via an IOException from the final flush.
}
}
}
笔记:
- 标准的Java包装流,读取器和写入器都传播并传播到他们的包装流等。因此,您只需要关闭或冲洗最外层的包装器即可。
close
flush
- 在 try 块的末尾显式刷新的目的是使 (real) 处理程序能够看到任何写入失败1。
IOException
- 当您对输出流执行关闭或刷新时,由于光盘错误或文件系统已满,可能会引发“蓝月亮中的一次”异常。你不应该压扁这个例外!
如果您经常需要“关闭可能为空的流,忽略 IOExceptions”,那么您可以为自己编写一个帮助器方法,如下所示:
public void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ex) {
// ignore
}
}
}
然后,您可以将上一个最终块替换为:
} finally {
closeQuietly(oos);
}
另一个答案指出,一种方法已经在Apache Commons库中可用......如果您不介意为10行方法的项目添加依赖项。closeQuietly
但请注意,您只在 IO 异常确实无关紧要的流上使用。closeQuietly
更新:在Apache Commons API的2.6版本中已弃用。Java 7+ try-with-resources 使它变得多余。closeQuietly
关于人们在评论中询问的对立问题:flush()
close()
-
标准的“筛选器”和“缓冲”输出流和写入器具有一个 API 协定,该协定声明导致所有缓冲输出被刷新。您应该发现执行输出缓冲的所有其他(标准)输出类的行为方式相同。因此,对于标准类,在 紧接之前调用是多余的。close()
flush()
close()
-
对于自定义类和第三方类,您需要进行调查(例如,读取javadoc,查看代码),但是任何不刷新缓冲数据的方法都可以说是坏的。close()
-
最后,还有一个问题,即实际作用是什么。javadoc说的是这个(对于...flush()
OutputStream
如果此流的预期目标是底层操作系统(例如文件)提供的抽象,则刷新流仅保证将先前写入流的字节传递到操作系统进行写入;它不保证它们实际上被写入物理设备,如磁盘驱动器。
所以。。。如果你希望/想象调用保证你的数据会持续存在,你错了!(如果你需要做那种事情,看看方法......flush()
FileChannel.force