java在finally中关闭资源_获取/关闭资源时Java try/catch/finally最佳实践

Stephen C..

53

如果您尝试从源头捕获并报告所有异常,则更好的解决方案是:

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块结束时显式刷新的目的是使(实际)处理程序IOException能够看到任何写入失败1.

当您对输出流执行关闭或刷新时,由于光盘错误或文件系统已满而导致异常将被"抛出一个蓝月亮". 你不应该压制这个例外!.

如果你经常需要"关闭一个忽略IOExceptions的可能为空的流",那么你可以自己编写一个这样的辅助方法:

public void closeQuietly(Closeable closeable) {

if (closeable != null) {

try {

closeable.close();

} catch (IOException ex) {

// ignore

}

}

}

然后你可以用以下代码替换之前的finally块:

} finally {

closeQuietly(oos);

}

(另一个答案指出,一个closeQuietly方法已经在Apache Commons库中可用了......如果你不介意为你的项目添加10行方法的依赖项. 更新:请注意这些方法在版本2.6中不推荐使用API).

但请注意,您只能closeQuietly在IO异常真正无关的流上使用.

1 - 使用try-with-resources时不需要这样做.

论问题flush()与close()人们的询问:

标准的"过滤器"和"缓冲"输出流和close()写入器具有API合同,该合同声明会刷新所有缓冲的输出.您应该发现执行输出缓冲的所有其他(标准)输出类的行为方式相同.因此,对于标准类,flush()之前立即调用是多余的close().

对于自定义和第三方类,您需要进行调查(例如,阅读javadoc,查看代码),但任何close()不刷新缓冲数据的方法都可能被破坏.

最后,还有flush()实际问题.javadoc说的是这个(对OutputStream......)

如果该流的预期目的地是由底层操作系统提供的抽象,例如文件,则刷新流仅保证先前写入流的字节被传递到操作系统以进行写入; 它不能保证它们实际上写入物理设备,如磁盘驱动器.

所以...如果您希望/想象调用flush()保证您的数据将持续存在,那么您错了! (如果你需要做那种事情,看看FileChannel.force方法......)

另一方面,如果您可以使用Java 7或更高版本,则@Mike Clark的答案中描述的"新"试用资源是最佳解决方案.

如果您没有使用Java 7或更高版本来使用新代码,那么您可能陷入了深深的困境并深入挖掘.

从开始到结束,这似乎太脏了。Java真的很奇怪吗? (2认同)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值