用下面的 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 JadeLove 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 ![]() 我错了。我傻子。请不要看我。 |
![]() | 7 narutow OP @RedBeanIce 是的, 但如果写在 finally 中的 close 再抛异常, 说明 close 失败了, 这时候该怎么处理呢 |
![]() | 8 RedBeanIce 2021-03-12 10:46:55 +08:00 ![]() @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 ![]() IO Stream 的 close()的异常,基本上都不是关闭连接产生的异常而是重复关闭连接产生的。 |
![]() | 16 dreamist 2021-03-12 17:42:51 +08:00 ![]() 首先,try-with-resource 并不能解决这个问题,因为它本质上是编译器的语法糖,和自己写 try catch finally 一样的。然后关于这个问题,如果真的出现了 close 也也出现异常的情况,那么其实是没有什么好的办法的了,无法再确定它内部是不是真的关闭了的。 |
![]() | 17 ikas 2021-03-13 16:32:39 +08:00 假设 close 出错了,那这个错误可能会对将来的执行造成影响,这时候,错误还是会产生,还是有机会再见的~,这时候就会来检查,为啥关闭不了~,如果是业务有要求,那么关闭的时候出错,你必然是要做处理的,或者继续 throw |