为什么我只能从okhttp.Response InputStream中一次读取2048个字节?

时间:2014-09-24 17:49:39

标签: java android networking okhttp okio

我正在使用OkHttp GET请求下载文件:

import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
...
OkHttpClient okClient = new OkHttpClient();
Request request = Request.Builder().url(url).get();
Response response = okClient.newCall(request).execute();

我从响应正文中读取并使用BufferedInputStream进行装饰,缓冲区大小为4096:

BufferedInputStream in = new BufferedInputStream(response.body().byteStream(), 4096);

但是,当我尝试从缓冲区读取时,第一次读取返回1179字节。之后,我一次只能读取2048个字节:

byte[] buffer = new byte[4096];
while (true) {
    int bytesRead = in.read(buffer); //bytesRead is always 2048, except the first read
    if (bytesRead == -1) break;
}

几个相关问题:

  1. 什么可能导致第一次读取返回1179字节?某种文件头?
  2. 为什么从InputStream的页面读取大小为2048字节,而不是BufferedInputStream包装器指定的值?
  3. 有没有办法配置OkHttpClient从缓冲区读取超过2048个字节?

1 个答案:

答案 0 :(得分:4)

  

什么可能导致第一次读取返回1179字节?某种文件头?

对于您正在阅读的响应,HTTP标头为869字节。

  

为什么从InputStream中读取的内容大小为2048字节,而不是BufferedInputStream包装器指定的值?

你必须深入挖掘BufferedInputStream,找出为什么它没有加入两页。

来自OkHttp的InputStream正在处理2048个块,因为它使用了一个池来保存分配。

  

有没有办法配置OkHttpClient从缓冲区读取超过2048个字节?

没有


根据您的工作情况,您通常可以更好地使用BufferedSource中的response.body().source()而非使用BufferedInputStream。您可以在Okio repo上了解有关它们的更多信息。