Java 读写 Stream 时, 如果 close 失败了, 应该怎样保证 Stream 最终会被关闭呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
narutow
V2EX    Java

Java 读写 Stream 时, 如果 close 失败了, 应该怎样保证 Stream 最终会被关闭呢?

  •  
  •   narutow 2021-03-12 10:20:12 +08:00 3923 次点击
    这是一个创建于 1673 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用下面的 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(); } } 
    17 条回复    2021-03-13 16:32:39 +08:00
    JadeLove
        1
    JadeLove  
       2021-03-12 10:28:46 +08:00
    用 try-with-resources
    zpf124
        2
    zpf124  
       2021-03-12 10:29:02 +08:00
    一般都是 close 抛异常不怎么处理,甚至错误打印有时候都没有。

    因为 close 一般报错都是 流已经被关闭的错误。
    比如你在其他地方已经执行过一次 close 了或者流的另一端已经直接端口了。
    xiecanmy
        3
    xiecanmy  
       2021-03-12 10:35:34 +08:00
    用 try-with-resources


    try(OutputStream out = new FileOutputStream("")) {

    // ...操作流代码
    } catch (Exception e) {
    e.printStackTrace();
    }
    Oktfolio
        4
    Oktfolio  
       2021-03-12 10:35:40 +08:00
    try (OutputStream out = new FileOutputStream("")) {

    } catch (Exception e) {
    e.printStackTrace();
    }
    RedBeanIce
        5
    RedBeanIce  
       2021-03-12 10:38:13 +08:00
    因为 finally 一定会执行。。。
    RedBeanIce
        6
    RedBeanIce  
       2021-03-12 10:38:46 +08:00   4
    我错了。我傻子。请不要看我。
    narutow
        7
    narutow  
    OP
       2021-03-12 10:39:11 +08:00
    @RedBeanIce 是的, 但如果写在 finally 中的 close 再抛异常, 说明 close 失败了, 这时候该怎么处理呢
    RedBeanIce
        8
    RedBeanIce  
       2021-03-12 10:46:55 +08:00   1
    @narutow 请看 6 楼,我是傻子我是傻子我是傻子
    Still4
        9
    Still4  
       2021-03-12 12:20:12 +08:00
    finally 最好只放最简单的逻辑,比如断开连接,直接变量置空,干净利落的切掉

    你这个例子里面,不得不调用可能抛出异常的代码,只能无视了,还能咋办呢....
    iseki
        10
    iseki  
       2021-03-12 12:27:19 +08:00 via Android
    一般不处理吧,你不能无限兜底,另外如果 finally 里抛了异常会被抑制,见 suppress
    ychost
        11
    ychost  
       2021-03-12 12:34:31 +08:00
    1. try-with-resource
    2. lombok @Clean
    当然都无法解决你说的问题,在 finally 里面 抛异常了,不能无限兜底的
    hantsy
        12
    hantsy  
       2021-03-12 14:32:36 +08:00
    以为是 Stream API 。

    IO Stream 基本都是可以 Try (初始化 Stream ){},主要看它是否实现 Closable 接口。
    newmlp
        13
    newmlp  
       2021-03-12 14:59:02 +08:00
    close 不可能失败的,
    Brentwans
        14
    Brentwans  
       2021-03-12 15:44:42 +08:00
    大概明白你的疑问,你的问题应该是异常处理没弄明白。这里 close 失败的异常,是让处理后事用的。假设,你的输出流是将新增的内存数据持久化写到磁盘用的。close 关闭失败,意味着持久化失败了,这个时候可能的处理是将新增加的数据对象从内存删除,恢复到添加之前的样子。
    需要强制处理的异常,通常是处理后事用的,下层没处理最好还是抛出上层处理。二话不说默认异常输出到志,这个代码会有问题的。
    cheng6563
        15
    cheng6563  
       2021-03-12 17:41:36 +08:00   1
    IO Stream 的 close()的异常,基本上都不是关闭连接产生的异常而是重复关闭连接产生的。
    dreamist
        16
    dreamist  
       2021-03-12 17:42:51 +08:00   1
    首先,try-with-resource 并不能解决这个问题,因为它本质上是编译器的语法糖,和自己写 try catch finally 一样的。然后关于这个问题,如果真的出现了 close 也也出现异常的情况,那么其实是没有什么好的办法的了,无法再确定它内部是不是真的关闭了的。
    ikas
        17
    ikas  
       2021-03-13 16:32:39 +08:00
    假设 close 出错了,那这个错误可能会对将来的执行造成影响,这时候,错误还是会产生,还是有机会再见的~,这时候就会来检查,为啥关闭不了~,如果是业务有要求,那么关闭的时候出错,你必然是要做处理的,或者继续 throw
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2842 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 70ms UTC 14:07 PVG 22:07 LAX 07:07 JFK 10:07
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86