阅读 HttpURLConnection InputStream - 手动缓冲区还是 BufferedInputStream?

Posted

技术标签:

【中文标题】阅读 HttpURLConnection InputStream - 手动缓冲区还是 BufferedInputStream?【英文标题】:Reading HttpURLConnection InputStream - manual buffer or BufferedInputStream? 【发布时间】:2011-02-17 02:26:05 【问题描述】:

在读取 HttpURLConnection 的 InputStream 时,是否有任何理由使用以下其中一个而不是另一个?我已经在示例中看到了这两种用法。

手动缓冲:

while ((length = inputStream.read(buffer)) > 0) 
    os.write(buf, 0, ret);

BufferedInputStream

is = http.getInputStream();
bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);

int current = 0;
while ((current = bis.read()) != -1) 
     baf.append(current);

编辑总的来说,我对 HTTP 还很陌生,但我想到的一个考虑是,如果我使用的是持久 HTTP 连接,我不能在输入流为空之前读取正确的?在这种情况下,我不需要读取消息长度并只读取该长度的输入流吗?

同样,如果不使用持久连接,我包含的代码在正确读取流方面是否 100% 好?

【问题讨论】:

什么是ByteArrayBuffer?但是当你可以处理字节数组时,没有任何理由处理单个字节。 【参考方案1】:

我在我的博客上的一篇关于在 android 中使用 JSON 的文章中谈到了一个很好的方法。 http://blog.andrewpearson.org/2010/07/android-why-to-use-json-and-how-to-use.html。我将在下面发布相关帖子的相关部分(代码非常通用):

InputStream in = null;
String queryResult = "";
try 
     URL url = new URL(archiveQuery);
     HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
     HttpURLConnection httpConn = (HttpURLConnection) urlConn;
     httpConn.setAllowUserInteraction(false);
     httpConn.connect();
     in = httpConn.getInputStream();
     BufferedInputStream bis = new BufferedInputStream(in);
     ByteArrayBuffer baf = new ByteArrayBuffer(50);
     int read = 0;
     int bufSize = 512;
     byte[] buffer = new byte[bufSize];
     while(true)
          read = bis.read(buffer);
          if(read==-1)
               break;
          
          baf.append(buffer, 0, read);
     
     queryResult = new String(baf.toByteArray());
      catch (MalformedURLException e) 
          // DEBUG
          Log.e("DEBUG: ", e.toString());
      catch (IOException e) 
          // DEBUG
          Log.e("DEBUG: ", e.toString());
     

【讨论】:

有一个明确但需要解决的问题:您应该始终指定用于将字节转换为字符串的编码 (new String(baf.toByteArray(), "UTF-8")。【参考方案2】:

关于持久的 HTTP 连接,情况正好相反。您应该从输入流中读取所有内容。否则Java HTTP客户端不知道HTTP请求已经完成,socket连接可以重用。

见http://java.sun.com/javase/6/docs/technotes/guides/net/http-keepalive.html:

您可以做些什么来帮助 Keep-Alive?

不要放弃连接 忽略响应体。这样做 可能会导致空闲的 TCP 连接。 那需要被垃圾收集 当它们不再被引用时。

如果 getInputStream() 成功 返回,读取整个响应 身体。

【讨论】:

【参考方案3】:

使用前者——后者与第一个相比没有真正的好处,而且速度稍慢;即使缓冲,逐字节读取内容也是低效的(尽管没有缓冲时速度非常慢)。这种阅读方式在 C 语言中已经过时了。虽然在您需要找到某种结束标记的情况下可能很有用。

【讨论】:

【参考方案4】:

仅当您使用 BufferedInputStream 特定的方法时。

【讨论】:

对问题的进一步说明。 BufferedInputStream--具体的方法比如什么?它不会导出除InputStream 定义的方法以外的任何方法。

以上是关于阅读 HttpURLConnection InputStream - 手动缓冲区还是 BufferedInputStream?的主要内容,如果未能解决你的问题,请参考以下文章

java发送get,post请求

如何在 HttpURLConnection 中发送 PUT、DELETE HTTP 请求?

用Java阅读网页

安全使用 HttpURLConnection

HttpURLConnection 超时设置

Android之HttpURLConnection