使用OKHTTP下载二进制文件

86

我在我的Android应用程序中使用OKHTTP客户端进行网络通信。

这个例子展示了如何上传二进制文件。我想知道如何使用OKHTTP客户端获取二进制文件下载的输入流。

以下是该示例的清单:

public class InputStreamRequestBody extends RequestBody {

    private InputStream inputStream;
    private MediaType mediaType;

    public static RequestBody create(final MediaType mediaType, 
            final InputStream inputStream) {
        return new InputStreamRequestBody(inputStream, mediaType);
    }

    private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) {
        this.inputStream = inputStream;
        this.mediaType = mediaType;
    }

    @Override
    public MediaType contentType() {
        return mediaType;
    }

    @Override
    public long contentLength() {
        try {
            return inputStream.available();
        } catch (IOException e) {
            return 0;
        }
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        Source source = null;
        try {
            source = Okio.source(inputStream);
            sink.writeAll(source);
        } finally {
            Util.closeQuietly(source);
        }
    }
}

简单的GET请求的当前代码如下:

OkHttpClient client = new OkHttpClient();
request = new Request.Builder().url("URL string here")
                    .addHeader("X-CSRFToken", csrftoken)
                    .addHeader("Content-Type", "application/json")
                    .build();
response = getClient().newCall(request).execute();

现在我该如何将响应转换为 InputStream 。与 Apache HTTP Client 的响应类似,对于 OkHttp 响应,可以使用以下内容:

InputStream is = response.getEntity().getContent();

编辑

接受下面的答案。 我修改后的代码:

request = new Request.Builder().url(urlString).build();
response = getClient().newCall(request).execute();

InputStream is = response.body().byteStream();

BufferedInputStream input = new BufferedInputStream(is);
OutputStream output = new FileOutputStream(file);

byte[] data = new byte[1024];

long total = 0;

while ((count = input.read(data)) != -1) {
    total += count;
    output.write(data, 0, count);
}

output.flush();
output.close();
input.close();

请检查我的修改后的答案,我正在等待您的反馈。 - Nadir Belhaj
很高兴它对你有用,伙计 :D - Nadir Belhaj
顺便提一下,如果请求中出现ioexception并且HttpEngine设置为重试,则您的InputStreamRequestBody将无法正常工作。请参见https://github.com/square/okhttp/blob/master/okhttp/src/main/java/com/squareup/okhttp/Call.java第202行,writeTo在while循环中被调用。这将导致错误。(我在从“content://”inputstream上传时偶然发现了这个问题) - njzk2
11个回答

0
    val request = Request.Builder().url(URL).build()
    val response = OkHttpClient().newCall(request).execute()

    val `is`: InputStream = response.body!!.byteStream()

    val PATH = (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        .toString() + "/Folder")
    val file = File(PATH)

    if (!file.exists()) file.mkdir()  
  
        val outputFile = File(file, getFileName(URL))

        val input = BufferedInputStream(`is`)
        val output: OutputStream = FileOutputStream(outputFile)

        val data = ByteArray(1024)

        var total: Long = 0

         while (`is`.read(data).also { total = it.toLong() } != -1) {
             output.write(data, 0, total.toInt())
         }

        output.flush()
        output.close()
        input.close()

目前你的回答不够清晰。请编辑并添加更多细节,以帮助其他人理解它如何回答所提出的问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接