【问题标题】:Factors deciding the number of bytes read from the InputStream决定从 InputStream 读取的字节数的因素
【发布时间】:2018-02-17 10:27:20
【问题描述】:

从urlConnection.getInputStream()获取的InputStream向ByteArrayOutputStream写入数据的处理耗时1分钟以上。

代码 片段

URL requestUrl= new URL(_sampleurl_);  
HttpURLConnection urlConnection=(HttpURLConnection)requestUrl.openConnection();  
urlConnection.setConnectTimeout(10000);  
urlConnection.setReadTimeout(10000);  
urlConnection.setRequestMethod("GET");  
urlConnection.connect();  
int statusCode=urlConnection.getResponseCode();   //200  
long contentLengthByTen = urlConnection.getHeaderFieldLong("Content-Length", _defaultSize_); //7631029  
InputStream inputStream = urlConnection.getInputStream();  
final byte[] byteArray = new byte[16384];  
int length;  
ByteArrayOutputStream byteArrOutStrm = new ByteArrayOutputStream();  
int k = 0;  
while ((length = inputStream.read(byteArray)) != -1)  
{  
    byteArrOutStrm.write(byteArray, 0, length);  
    k++;  
} 

一些观察结果是:
while 循环单独执行超过一分钟,它迭代了大约 2650 次。
HttpURLConnection 响应码为 200,因此整个内容都在 InputStream 中可用。
该文件的 Content-Length 为 7631029(字节)。

我有两个问题:

  1. 虽然字节数组大小为16384,状态码为200,但inputStream.read方法平均只读取2800字节。为什么以及哪些因素决定了这些字节?
  2. 减少处理时间的适当解决方案?

【问题讨论】:

  • "HttpURLConnection 响应码为 200,因此整个内容都在 InputStream 中可用。"这并不意味着整个内容已经发送
  • 因此,这也不意味着现在可以在套接字接收缓冲区中获得全部内容,以便在一次读取中读取。发送端仍然存在 I/O 和刷新、分段和打包,以及网络中的丢包和重传。
  • 是的。我误会了,200状态码表示请求成功完成,实际上表示请求成功(OK)。

标签: networking inputstream httpurlconnection bytearrayoutputstream


【解决方案1】:
  1. 虽然字节数组大小为16384,状态码为200,但inputStream.read方法平均只读取2800字节。为什么以及哪些因素决定了这些字节?

套接字接收缓冲区中可用的字节数,这又是发送方速度、接收方读取频率、网络带宽和路径 MTU 的函数。您所看到的并不令人惊讶:这表明您与发件人的联系非常好。

  1. 减少处理时间的适当解决方案?

让发件人更快地发送。您的接收代码没有任何问题,尽管我想知道为什么您在使用它之前要在 ByteArrayOutputStream 中收集整个响应。这只会浪费内存并增加延迟。

【讨论】:

  • 谢谢 EJP。请注意,该问题是由于来自发送方的响应数据的延迟造成的。仅供参考,sampleurl 是用户提供的音频 url,它的二进制内容写入 ByteArrayOutputStream,然后将其转换为字节数组以进行进一步的音频处理。
猜你喜欢
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 2015-07-11
  • 2012-12-25
  • 2021-03-22
  • 2020-03-11
相关资源
最近更新 更多