Java 为什么将输入读取为流比读取字符串更节省内存?
我们正在使用HTTPClient实现RESTAPI 我们正在使用以下命令读取服务器响应:Java 为什么将输入读取为流比读取字符串更节省内存?,java,stream,httpclient,Java,Stream,Httpclient,我们正在使用HTTPClient实现RESTAPI 我们正在使用以下命令读取服务器响应: method = new PostMethod(url); HttpClient client = new HttpClient(); int statusCode = client.executeMethod(method); String responseBody = method.getResponseBodyAsString(); 当我们这样做时,我们会得到以下警告: Dec 9, 2009 7:
method = new PostMethod(url);
HttpClient client = new HttpClient();
int statusCode = client.executeMethod(method);
String responseBody = method.getResponseBodyAsString();
当我们这样做时,我们会得到以下警告:
Dec 9, 2009 7:41:11 PM org.apache.commons.httpclient.HttpMethodBase getResponseBody
WARNING: Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
他们接着说:
HttpClient能够高效地
请求/响应正文流。大的
可以提交或接收实体
没有在内存中缓冲。这
如果有多个
可以执行HTTP方法
同时虽然有
方便的处理方法
字符串或字节等实体
不鼓励使用数组。
除非小心使用,否则它们很容易损坏
导致内存不足的情况,
因为它们意味着缓冲
内存中的完整实体
因此,我的问题是,如果您确实需要完整的响应作为字符串(即:存储在DB中,或使用DOM进行解析),为什么使用流会更节省内存?整个过程并没有更节省内存。如果您从一个流中读取数据并将其放入字符串中,那么您只是将流程分成两部分,以便HttpClient类不会注意到它
如果确实需要整个字符串,则可以忽略警告。然后由您来确保每个请求不会占用太多内存,这样服务器就不会轻易被拒绝服务攻击打倒。您的问题混淆了这一点 如果您确实需要整个响应作为字符串,那么就这样做 但是,如果你能侥幸逃脱,那就使用流 当您将整个响应加载到字符串中时,整个响应主体一次出现在内存中 使用流,每次只有一小部分响应保存在内存中
文档中说,尤其是同时处理多个大型请求时,将整个请求体加载到字符串中需要大量内存。使用流比将整个实体作为字符串使用更有效,因为后者意味着
只有当您有一个用例,可以在拥有整个响应主体之前开始处理响应时,您才可以使用流的效率。如果您要解析到
org.w3c.Document
(或者更好的是,org.jdom.Document
),直接使用流确实很容易。例:
org.apache.http.HttpResponse hr = httpClient.execute(httpRequest);
org.apache.http.HttpEntity he = hr.getEntity();
org.jdom.input.SAXBuilder builder = new SAXBuilder();
org.jdom.Document document = builder.build(he.getContent());