为了账号安全,请及时绑定邮箱和手机立即绑定

BufferedReader关闭流的问题

BufferedReader关闭流的问题

慕慕森 2019-03-29 18:15:08
线上代码,如何正确的关闭BufferedReader流。我用的JDK1.7原来的代码如下:public static String httpPostWithJson(String ecUrl, String params) {        try {            // 创建连接            URL url = new URL(ecUrl);            HttpURLConnection connection = (HttpURLConnection) url.openConnection();            connection.setDoOutput(true);            connection.setDoInput(true);            connection.setRequestMethod("POST");            connection.setUseCaches(false);            connection.setInstanceFollowRedirects(true);            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");            connection.connect();            // POST请求            DataOutputStream out = new DataOutputStream(connection.getOutputStream());            out.writeBytes(params);            out.flush();            out.close();            // 读取响应            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));            String lines;            StringBuffer sb = new StringBuffer("");            while ((lines = reader.readLine()) != null) {                lines = new String(lines.getBytes(), "utf-8");                sb.append(lines);            }            // System.out.println(sb);            reader.close();            // 断开连接            connection.disconnect();            return sb.toString();        } catch (MalformedURLException e) {            logger.error("httpPostWithJsonMalformedURLException error", e);            e.printStackTrace();        } catch (UnsupportedEncodingException e) {            logger.error("httpPostWithJsonUnsupportedEncodingException error", e);            e.printStackTrace();        } catch (IOException e) {            logger.error("httpPostWithJsonIOException error", e);            e.printStackTrace();        }        return null;    }这样虽然在finally中关闭了流,但是又要在finally中引入IOException,这样是不是很麻烦啊关于关闭流,还有没有好的措施或者实践经验呢?谢谢~~补充:JDK 1.7但是不能用Try-with-resources机制
查看完整描述

4 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

这个问题其实无须过多困扰。也没有必要往JDK1.7的try-with-resources上扯。
首先关闭资源放在try块里一定会有问题:资源可能不被关闭。
所以资源的关闭应该放在finally里,这没有什么疑问。
至于finally块里close资源会额外引入IOE,这也是无法避免的。
目前(就我见到过的)绝大多数代码里,捕获IOE后,最多打一条log,更多的是noop,即no operations,do nothing
close的时候IOE发生的几率很小,它应该属于一种操作系统层面的error,选择忽略它是正确的选择,毕竟你的系统不能因为一个资源关闭错误而停止运行。况且,如果你硬要捕获这个IOE,那能做些什么呢。

如果不想在finally块里引入try-catch,我见过guava的一种关闭方式,写个工具方法叫做closeQuietly(),不吵不闹就挺好。


查看完整回答
反对 回复 2019-04-21
?
aluckdog

TA贡献1847条经验 获得超7个赞

可以考虑Java7的try with resource


try (BufferedReader br = ...) {

    //...

} catch (IOException ex) {

    //...

}

参考


查看完整回答
反对 回复 2019-04-21
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

同意1楼的答案,你补充的问题,也是由于IDE的问题。


另外对于实现了 AutoCloseable 和 Closeable 接口的资源,最好都使用 try-with-resources结构。


以你的代码作为例子,省略了一些代码


try{

    reader.readline();

}catch(IOException e){

    e.printStackTrace();

}finally {

    try {

       reader.close();

    } catch (IOException e) {

       e.printStackTrace();

    }

}

假设 readline 和 close 都发生io异常,使用 JDK1.7 前的异常捕捉结构,只能捕捉到 close 的异常,readline 的异常被抑制了。(因为 finally 的代码必须执行)


另外一个问题,在 try-with-resources 中资源的 AutoCloseable 的 close 方法什么时候执行?


在执行完 try 代码块的代码之后就会执行(这里不贴实验代码了),所以使用 try-with-resources 的结构,catch 块和 finally 块都是在资源进行关闭之后才会执行的。


查看完整回答
反对 回复 2019-04-21
  • 4 回答
  • 0 关注
  • 2119 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信