我创建了一个小型抓取类,下面的方法从页面中读取文本。
但是,我发现该方法无法正确关闭连接。这会导致大量打开连接,导致我的托管公司随后暂停我的帐户。以下是正确的吗?
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;
}
最佳答案
您的代码在成功案例中没有问题,但在失败案例中可能会泄漏连接(当 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()
连接,除非你确定在不久的将来不会再有任何对该主机的 url 请求 - disconnect()
将阻止后续请求通过现有连接进行管道传输,这对于 https 来说尤其会显着降低速度。
关于java - BufferedReader 连接未关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24157345/