android binary file,Download binary file from OKHTTP

可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):

问题:

I am using OKHTTP client for networking in my android application.

This example shows how to upload binary file. I would like to know how to get inputstream of binary file downloading with OKHTTP client.

Here is the listing of the example : 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); } } }

Current code for simple get request is: 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();

Now how do I convert the response to InputStream. Something similar to response from Apache HTTP Client like this for OkHttp response: InputStream is = response.getEntity().getContent();

EDIT

Accepted answer from below. My modified code: 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();

回答1:

Getting ByteStream from OKHTTP

I've been digging around in the Documentation of OkHttp you need to go this way

use this method : response.body().byteStream() wich will return an InputStream

so you can simply use a BufferedReader or any other alternative 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 in = response.body().byteStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String result, line = reader.readLine(); result = line; while((line = reader.readLine()) != null) { result += line; } System.out.println(result); response.body().close();

回答2:

For what it's worth, I would recommend response.body().source() from okio (since OkHttp is already supporting it natively) in order to enjoy an easier way to manipulate a large quantity of data that can come when downloading a file. @Override public void onResponse(Call call, Response response) throws IOException { File downloadedFile = new File(context.getCacheDir(), filename); BufferedSink sink = Okio.buffer(Okio.sink(downloadedFile)); sink.writeAll(response.body().source()); sink.close(); }

A couple of advantages taken from the documentation in comparison with InputStream: This interface is functionally equivalent to InputStream. InputStream requires multiple layers when consumed data is heterogeneous: a DataInputStream for primitive values, a BufferedInputStream for buffering, and InputStreamReader for strings. This class uses BufferedSource for all of the above. Source avoids the impossible-to-implement available() method. Instead callers specify how many bytes they require.

Source omits the unsafe-to-compose mark and reset state that's tracked by InputStream; callers instead just buffer what they need.

When implementing a source, you need not worry about the single-byte read method that is awkward to implement efficiently and that returns one of 257 possible values.

And source has a stronger skip method: BufferedSource.skip(long) won't return prematurely.

回答3:

This is how I use Okhttp + Okio libraries while publishing download progress after every chunk download: public static final int DOWNLOAD_CHUNK_SIZE = 2048; //Same as Okio Segment.SIZE try { Request request = new Request.Builder().url(uri.toString()).build(); Response response = client.newCall(request).execute(); ResponseBody body = response.body(); long contentLength = body.contentLength(); BufferedSource source = body.source(); File file = new File(getDownloadPathFrom(uri)); BufferedSink sink = Okio.buffer(Okio.sink(file)); long totalRead = 0; long read = 0; while (read = (source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) { totalRead += read; int progress = (int) ((totalRead * 100) / contentLength); publishProgress(progress); } sink.writeAll(source); sink.flush(); sink.close(); publishProgress(FileInfo.FULL); } catch (IOException e) { publishProgress(FileInfo.CODE_DOWNLOAD_ERROR); Logger.reportException(e); }

回答4:

Better solution is to use OkHttpClient as: OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://publicobject.com/helloworld.txt") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); // Headers responseHeaders = response.headers(); // for (int i = 0; i < responseHeaders.size(); i++) { // System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i)); // } // System.out.println(response.body().string()); InputStream in = response.body().byteStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String result, line = reader.readLine(); result = line; while((line = reader.readLine()) != null) { result += line; } System.out.println(result); } });

回答5:

The best option to download (based on source code "okio") private void download(@NonNull String url, @NonNull File destFile) throws IOException { Request request = new Request.Builder().url(url).build(); Response response = okHttpClient.newCall(request).execute(); ResponseBody body = response.body(); long contentLength = body.contentLength(); BufferedSource source = body.source(); BufferedSink sink = Okio.buffer(Okio.sink(destFile)); Buffer sinkBuffer = sink.buffer(); long totalBytesRead = 0; int bufferSize = 8 * 1024; for (long bytesRead; (bytesRead = source.read(sinkBuffer, bufferSize)) != -1; ) { sink.emit(); totalBytesRead += bytesRead; int progress = (int) ((totalBytesRead * 100) / contentLength); publishProgress(progress); } sink.flush(); sink.close(); source.close(); }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值