BufferedReader连接未关闭

时间:2014-06-11 07:46:31

标签: java bufferedreader

我创建了一个小型的抓取类,下面的方法从页面中读取文本。

但是,我发现该方法无法正确关闭连接。这导致大量的打开连接,导致我的托管公司暂停我的帐户。以下是正确的吗?

private String getPageText(String urlString) {

    String pageText = "";


        BufferedReader reader = null;
        try {
            URL url = new URL(urlString);
            reader = new BufferedReader(new InputStreamReader(url.openStream()));
            StringBuilder builder = new StringBuilder();
            int read;
            char[] chars = new char[1024];
            while ((read = reader.read(chars)) != -1)
                builder.append(chars, 0, read); 

            pageText = builder.toString();
        } catch (MalformedURLException e) {
            Log.e(CLASS_NAME, "getPageText.MalformedUrlException", e);
        } catch (IOException e) {
            Log.e(CLASS_NAME, "getPageText.IOException", e);
        } finally {
            if (reader != null)
                try {
                    reader.close();
                } catch (IOException e) {
                    Log.e(CLASS_NAME, "getPageText.IOException", e);
                }
        }
        return pageText;


}

2 个答案:

答案 0 :(得分:2)

您的代码在成功案例中没有问题但在故障情况下可能会泄漏连接(当http服务器返回4xx或5xx状态代码时)。在这些情况下,HttpURLConnection通过.getErrorStream()而不是.getInputStream()提供响应正文,您应该确保排出并关闭该流。

URLConnection conn = null;
BufferedReader reader = null;
try {
  conn = url.openConnection();
  reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
  // ...
} finally {
  if(reader != null) {
    // ...
  }
  if(conn instanceof HttpURLConnection) {
    InputStream err = ((HttpURLConnection)conn).getErrorStream();
    if(err != null) {
      byte[] buf = new byte[2048];
      while(err.read(buf) >= 0) {}
      err.close();
    }
  }
}

最终可能还需要另外一层try / catch,但你明白了。您应该明确.disconnect()该连接,除非您确定在不久的将来不再有该主机上的网址请求 - disconnect()将阻止后续请求通过在现有连接上进行流水线操作,特别是对于https来说,这将大大减慢速度。

答案 1 :(得分:1)

您只是关闭stream而非connection,请使用以下结构:

URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection)
        u.openConnection();
conn.connect();

reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

然后:

} finally {
    if (reader != null)
       try {
           reader.close();
       } catch (IOException e) {
           Log.e(CLASS_NAME, "getPageText.IOException", e);
       }
    }

    try {
        if (conn != null) {
            conn.disconnect();
        }
    } catch (Exception ex) {}
}