5

我正在使用 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 个字节?
4

1 回答 1

5

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

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

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

您必须深入研究BufferedInputStream以找出为什么它没有将两个页面连接在一起。

OkHttpInputStream正在处理 2048 个块,因为它使用它们的池来保存分配。

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

不。


根据您在做什么,通常使用BufferedSourcefromresponse.body().source()而不是使用BufferedInputStream. 您可以在Okio repo上了解更多关于它们的信息。

于 2014-09-24T18:25:57.397 回答