【问题标题】:OkHttpClient response 206 exceptionOkHttpClient 响应 206 异常
【发布时间】:2019-04-29 04:06:52
【问题描述】:

我正在使用 OkHttpClient 为 android 应用程序从服务器下载 PDF 文件,下载时遇到 pdf 文件异常。

System.err: java.io.IOException: 206

这里是响应元素:

Date: Tue, 27 Nov 2018 12:45:17 GMT
Server: Apache/2.4.23 (Win64) PHP/5.6.25
Last-Modified: Mon, 09 Jan 2017 16:06:27 GMT
ETag: "392a0c-545ab8ccd2dc8"
Accept-Ranges: bytes
Content-Length: 1
Content-Range: bytes 3746315-3746315/3746316
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/pdf
OkHttp-Sent-Millis: 1543322716318
OkHttp-Received-Millis: 1543322716467

这是用于下载文件的代码:

private final static int BUFFER_SIZE = 1024 * 8;
Request.Builder requestBuilder = new Request.Builder().url(itemUrl);

try {
        Response response = 
        getOkHttpClient().newCall(requestBuilder.build()).execute();

        long totalSize = response.body().contentLength();

        if (response.code() != 200) {
            throw new IOException(String.valueOf(response.code()));
        }

        RandomAccessFile out = new RandomAccessFile(tempItemFilePath, "rw");

        byte[] buffer = new byte[BUFFER_SIZE];

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

        long bytesCount = 0;
        int bytesRead = 0;

        try {

            out.seek(out.length());

            while (true) {
                bytesRead = in.read(buffer, 0, BUFFER_SIZE);
                if (bytesRead == -1) {
                    break;
                }
                out.write(buffer, 0, bytesRead);
                manager.setDownloadStatus(magazine, ((bytesCount * 100) / totalSize));
                bytesCount += bytesRead;



                EventBus.getDefault().post(new DownloadStatusUpdateEvent());
            }
        } finally {
            out.close();
            if (in != null) {
                in.close();
            }
            in.close();
        }
        }

知道为什么它不起作用吗? PS:它适用于小于未下载的文件的文件。

【问题讨论】:

    标签: android http-headers okhttp


    【解决方案1】:

    问题是您正在执行 range request 请求组成响应的 3746316 个字节中的最后一个字节。

    根据 RFC 7233,您会收到 206 状态代码:

    206(部分内容)状态码表示服务器是 通过以下方式成功完成对目标资源的范围请求 转移所选表示的一个或多个部分 对应于在请求的 Range 中找到的可满足范围 标头字段(第 3.1 节)。

    你得到这个异常的原因是这段代码:

    if (response.code() != 200) {
        throw new IOException(String.valueOf(response.code()));
    }
    

    您应该检查的是响应是否成功(即它是否具有 2xx 状态),可以通过以下方式完成:

    if (!response.isSuccessful()) {
        throw new IOException(...);
    }
    

    请注意,尽管您的代码将成功创建带有响应内容的RandomAccessFile,即在这种情况下为单个字节,这可能不是预期的。

    【讨论】:

      猜你喜欢
      • 2012-04-06
      • 2011-03-18
      • 2017-08-23
      • 2020-11-08
      • 2014-05-15
      • 1970-01-01
      • 2016-09-13
      • 2016-04-30
      • 1970-01-01
      相关资源
      最近更新 更多