Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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(); 
like image 417
pratsJ Avatar asked Sep 17 '14 14:09

pratsJ


2 Answers

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.

like image 64
kiddouk Avatar answered Sep 17 '22 17:09

kiddouk


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(); 
like image 26
Nadir Belhaj Avatar answered Sep 21 '22 17:09

Nadir Belhaj