用下面的 java 代码读写流, 如果 close 发生了异常, 怎么保证流一定会被关闭呢? 还是说 close 都出错了, 那么就不管了, 直接挂掉?
OutputStream out = null;
try {
out = new FileOutputStream("");
// ...操作流代码
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
1
urzz 2021-03-12 10:28:46 +08:00
用 try-with-resources
|
2
zpf124 2021-03-12 10:29:02 +08:00
一般都是 close 抛异常不怎么处理,甚至错误打印有时候都没有。
因为 close 一般报错都是 流已经被关闭的错误。 比如你在其他地方已经执行过一次 close 了或者流的另一端已经直接端口了。 |
3
xiecanmy 2021-03-12 10:35:34 +08:00
用 try-with-resources
try(OutputStream out = new FileOutputStream("")) { // ...操作流代码 } catch (Exception e) { e.printStackTrace(); } |
4
Oktfolio 2021-03-12 10:35:40 +08:00
try (OutputStream out = new FileOutputStream("")) {
} catch (Exception e) { e.printStackTrace(); } |
5
RedBeanIce 2021-03-12 10:38:13 +08:00
因为 finally 一定会执行。。。
|
6
RedBeanIce 2021-03-12 10:38:46 +08:00 4
我错了。我傻子。请不要看我。
|
7
narutow OP @RedBeanIce 是的, 但如果写在 finally 中的 close 再抛异常, 说明 close 失败了, 这时候该怎么处理呢
|
8
RedBeanIce 2021-03-12 10:46:55 +08:00 1
@narutow 请看 6 楼,我是傻子我是傻子我是傻子
|
9
Still4 2021-03-12 12:20:12 +08:00
finally 最好只放最简单的逻辑,比如断开连接,直接变量置空,干净利落的切掉
你这个例子里面,不得不调用可能抛出异常的代码,只能无视了,还能咋办呢.... |
10
iseki 2021-03-12 12:27:19 +08:00 via Android
一般不处理吧,你不能无限兜底,另外如果 finally 里抛了异常会被抑制,见 suppress
|
11
ychost 2021-03-12 12:34:31 +08:00
|
12
hantsy 2021-03-12 14:32:36 +08:00
以为是 Stream API 。
IO Stream 基本都是可以 Try (初始化 Stream ){},主要看它是否实现 Closable 接口。 |
13
newmlp 2021-03-12 14:59:02 +08:00
close 不可能失败的,
|
14
Brentwans 2021-03-12 15:44:42 +08:00
大概明白你的疑问,你的问题应该是异常处理没弄明白。这里 close 失败的异常,是让处理后事用的。假设,你的输出流是将新增的内存数据持久化写到磁盘用的。close 关闭失败,意味着持久化失败了,这个时候可能的处理是将新增加的数据对象从内存删除,恢复到添加之前的样子。
需要强制处理的异常,通常是处理后事用的,下层没处理最好还是抛出上层处理。二话不说默认异常输出到日志,这个代码会有问题的。 |
15
cheng6563 2021-03-12 17:41:36 +08:00 1
IO Stream 的 close()的异常,基本上都不是关闭连接产生的异常而是重复关闭连接产生的。
|
16
dreamist 2021-03-12 17:42:51 +08:00 1
首先,try-with-resource 并不能解决这个问题,因为它本质上是编译器的语法糖,和自己写 try catch finally 一样的。然后关于这个问题,如果真的出现了 close 也也出现异常的情况,那么其实是没有什么好的办法的了,无法再确定它内部是不是真的关闭了的。
|
17
ikas 2021-03-13 16:32:39 +08:00
假设 close 出错了,那这个错误可能会对将来的执行造成影响,这时候,错误还是会产生,还是有机会再见的~,这时候就会来检查,为啥关闭不了~,如果是业务有要求,那么关闭的时候出错,你必然是要做处理的,或者继续 throw
|