【问题标题】:EntityUtils toString takes too long on big responsesEntityUtils toString 在大响应上花费的时间太长
【发布时间】:2012-12-04 01:16:10
【问题描述】:

以下代码:

//
// Define HTTP Post and content
//
HttpPost httppost = new HttpPost(url);
ByteArrayEntity be = new ByteArrayEntity(strPostData.getBytes("UTF-8"));
httppost.setEntity(be);
//
// Define HTTP Client
// 
HttpClient httpclient = new DefaultHttpClient();
HttpParams httpParameters = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10 * 1000);
//      
// Sets the default socket timeout
// in milliseconds which is the timeout for waiting for data.
//
int timeoutSocket = 10000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpResponse response = httpclient.execute(httppost);
//      
// This line takes too long on big responses
//
String content = EntityUtils.toString(response.getEntity());

当我的响应包含大量字节时,最后一行 (EntityUtils.toString) 耗时过长。

我正在使用 HTTP Post 检索 PDF 文件(最大 500 Kb),每个请求可能需要 1 或 2 秒,这太长了。

编辑信息:PDF 文件采用 base 64 编码并包装到 XML 标记中(字符串在接收后被解析)。

有什么方法可以让我的字符串响应更快?

编辑 2:为了知道我的 EntityUtils.toString 花了多少时间,我做了一个方法:

public static void logger(String header, String content) {
    Date dateActualLog = new Date();
    long milliseconds = (dateActualLog.getTime() - dateLastLog.getTime());
    Log.d(header, String.valueOf(milliseconds) + " => " + content);
    dateLastLog = dateActualLog;
}

(仅供参考:dateLastLog 是一个静态变量)

我把上面的代码修改成这样:

//      
// This line takes too long on big responses
//
logger(TAG, "toString ...");
String content = EntityUtils.toString(response.getEntity());
logger(TAG, "toString OK");

提前致谢。

【问题讨论】:

  • 不要那样做。您不能在字符串中存储任意二进制数据。
  • 我的 PDF 文件都是 base 64 编码并包装成 XML 标签,对不起,我没有提到,我现在编辑我的问题。
  • 你确定是toString() 的错吗?如果您尝试将响应正文读取为InputStream,该怎么办?
  • 我添加了 EDIT2 以获得更多信息,我尝试作为 inputStream 并没有改变治疗时间问题。
  • 所以,如果我理解正确,下载文件需要很长时间。那么,你的问题是什么?

标签: java http post


【解决方案1】:

嗯,首先要尝试的简单事情是确保您的网络服务器在 HTTP 响应中提供正确的 ContentLength 标头。查看 HttpCore 的 EntityUtils 类的某些版本的源代码,我们看到如果此信息不可用,则默认使用仅 4k 的 CharArrayBuffer,在写入时缓冲 1k 数据。在第 4 次、第 5 次和随后对 CharArrayBuffer 的写入(一直到 500,你说),它逐渐将缓冲区增加 1k ... 使用 System.arrayCopy()。呸。那里有你的表现痛苦。

但是,如果速度对您来说真的很重要,您将完全避免使用EntityUtils。将流变成临时的 500k String 是不负责任的……尤其是在电话上!您需要找到或编写 Base64DecodingInputStreamBase64DecodingReader 以将 InputStreamresponse.getEntity().getContent() 包装起来,并将其提供给您的解析器......而不是 String......。

【讨论】:

  • 非常感谢您详尽的解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
相关资源
最近更新 更多