【问题标题】:Binary File Download using OkHTTP Client get corrupted使用 OkHTTP 客户端下载的二进制文件损坏
【发布时间】:2019-01-21 14:40:19
【问题描述】:

我正在尝试使用 OkHttp 下载二进制文件并取得进展。
BUFFER_SIZE1 时,文件会正确下载。
但是,当我将BUFFER_SIZE 设置为1024 时,文件会损坏。
BUFFER_SIZE 设置为1 文件需要很长时间才能下载

下面是sn-p的代码:

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class DownloadTest {

    public static String url = "https://cdn.pixabay.com/photo/2017/02/06/12/34/reptile-2042906_1280.jpg";

    public static void main(String[] args) throws Exception {
        OkHttpClient client = new OkHttpClient();
        Call call = client.newCall(new Request.Builder().url(url).get().build());
        Response response = call.execute();

        System.out.println("" + response.headers().toString());
        System.out.println("" + response.body().contentLength());
        InputStream inputStream = response.body().byteStream();

        float contentLength = (float) response.body().contentLength();

        OutputStream fileOutputStream = new FileOutputStream(new File("myfile.jpg"));

        System.out.println("writing file " + contentLength);

        float downloaded = 0;

        /**
         * IF BUFFER_SIZE IS 1 file is downloaded properly
         * if BUFFER_SIZE is 1024 file is corrupted
         * open the downloaded image to test
         */
        //byte[] BUFFER_SIZE = new byte[1]; //Proper Download
        byte[] BUFFER_SIZE = new byte[1024]; //File Corrupt



        while (true) {
            int byteRead = inputStream.read(BUFFER_SIZE);
            if (byteRead == -1) {
                break;
            }

            downloaded += byteRead;

            fileOutputStream.write(BUFFER_SIZE);

            System.out.println(" " + downloaded + "/" + contentLength + " = " + ((downloaded / contentLength) * 100));

        }
        fileOutputStream.flush();
        fileOutputStream.close();

        System.out.println("file closed");
    }

}

【问题讨论】:

    标签: java inputstream okhttp3 fileoutputstream okhttp


    【解决方案1】:

    如果您的 BUFFER_SIZE 在上次读取时未满,那么您将在文件中写入错误的数据:

    你有

    fileOutputStream.write(BUFFER_SIZE);
    

    你应该有:

    fileOutputStream.write(BUFFER_SIZE, 0, byteRead);
    

    EDIT1:我也建议替换这部分代码:

    while (true) {
      int byteRead = inputStream.read(BUFFER_SIZE);
      if (byteRead == -1) {
        break;
      }
    

    采用更好的方法:

    int byteRead;
    while ( (byteRead = inputStream.read(BUFFER_SIZE)) > 0 ) {
    

    【讨论】:

      【解决方案2】:

      您的代码有点混乱,因为 BUFFER_SIZE 看起来像一个数字常量。除此之外,我认为您的问题出在 fileOutputStream.write(BUFFER_SIZE) 上。在最后一次写入时,当您的 byte[] 未“满”时,您仍将写入数组的全部内容。使用指定偏移量 (0) 和要写入的字节数 (byteRead) 的重载。

      【讨论】:

        猜你喜欢
        • 2017-05-27
        • 1970-01-01
        • 1970-01-01
        • 2014-11-11
        • 2020-10-18
        • 2015-03-16
        相关资源
        最近更新 更多