我目前使用以下函数来执行简单的HTTP GET。
public static String download(String url) throws java.io.IOException {
java.io.InputStream s = null;
java.io.InputStreamReader r = null;
//java.io.BufferedReader b = null;
StringBuilder content = new StringBuilder();
try {
s = (java.io.InputStream)new URL(url).getContent();
r = new java.io.InputStreamReader(s);
//b = new java.io.BufferedReader(r);
char[] buffer = new char[4*1024];
int n = 0;
while (n >= 0) {
n = r.read(buffer, 0, buffer.length);
if (n > 0) {
content.append(buffer, 0, n);
}
}
}
finally {
//if (b != null) b.close();
if (r != null) r.close();
if (s != null) s.close();
}
return content.toString();
}
我认为没有理由使用BufferedReader
,因为我只是按顺序下载所有内容。我是否认为在这种情况下BufferedReader
没有用处?
答案 0 :(得分:4)
在这种情况下,我会像你一样做(使用字节数组进行缓冲而不是其中一个流缓冲区)。
但也有例外。您看到缓冲区(此时输出)的位置在servlet API中。在调用 flush()之前,数据不会写入底层流,允许您缓冲输出,但如果发生错误则转储缓冲区并改为写入错误页面。如果需要使用 mark(int)和 reset()重置流以进行重读,则可以缓冲输入。例如,在决定将流传递给哪个内容处理程序之前,您可能会检查文件头。
不相关,但我认为你应该重写你的流处理。此模式最有效地避免资源泄漏:
InputStream stream = new FileInputStream("in");
try { //no operations between open stream and try block
//work
} finally { //do nothing but close this one stream in the finally
stream.close();
}
如果要打开多个流,请嵌套try / finally块。
您的代码正在做的另一件事是假设返回的内容是在VM的默认字符集中编码的(尽管这可能是足够的,具体取决于用例)。
答案 1 :(得分:1)
你是对的,如果你使用BufferedReader读取HTTP内容和标题,你会想要InputStreamReader所以你可以读取字节的字节。
在这种情况下BufferedReader有时会做一些奇怪的事情......特别是在阅读HTTP POST标题时,有时你将无法读取POST数据,如果使用InputStreamReader,你可以读取内容长度并读取很多内容字节...
答案 2 :(得分:1)
每次调用InputStreamReader的read()方法之一都可能导致从底层字节输入流中读取一个或多个字节。为了有效地将字节转换为字符,可以从基础流中提取比满足当前读取操作所需的更多字节。
答案 3 :(得分:0)
我的直觉告诉我,由于你已经使用字节数组执行缓冲,因此使用BufferedReader是多余的。