Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
OkHttp download file by Okio
import android.os.Environment;
import android.support.annotation.NonNull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.Util;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class FileUtil {
public static Observable<Integer> downloadFileByOkio(@NonNull final String url, @NonNull final File destFile) {
return Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
BufferedSink sink = null;
BufferedSource source = null;
try {
Request request = new Request.Builder().url(url).build();
Response response = HttpClientUtil.getInstance().getOkHttpClient().newCall(request).execute();
ResponseBody body = response.body();
long contentLength = body.contentLength();
source = body.source();
sink = Okio.buffer(Okio.sink(destFile));
Buffer sinkBuffer = sink.buffer();
long totalBytesRead = 0;
int bufferSize = 8 * 1024;
long bytesRead;
while ((bytesRead = source.read(sinkBuffer, bufferSize)) != -1) {
sink.emit();
totalBytesRead += bytesRead;
int progress = (int) ((totalBytesRead * 100) / contentLength);
subscriber.onNext(progress);
}
sink.flush();
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
} finally {
Util.closeQuietly(sink);
Util.closeQuietly(source);
}
subscriber.onCompleted();
}
}).throttleFirst(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
public static Observable<Integer> downloadFile(final String url) {
return Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
InputStream inputStream = null;
FileOutputStream outputStream = null;
try {
System.out.println("start download " + Thread.currentThread().getName() + " time " + System.currentTimeMillis());
OkHttpClient client = HttpClientUtil.getInstance().getOkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
inputStream = response.body().byteStream();
outputStream = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "a.txt"));
int totalCount = inputStream.available();
byte[] buffer = new byte[2 * 1024];
int len;
int readLen = 0;
while ((len = inputStream.read(buffer)) != -1 ) {
//System.out.println("download loop " + Thread.currentThread().getName());
outputStream.write(buffer, 0, len);
readLen += len;
subscriber.onNext(readLen);
}
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
subscriber.onCompleted();
}
});
}
}
@saket

This comment has been minimized.

Copy link

saket commented Aug 22, 2017

If you forego the progress part, the logic can be compressed to just a couple of lines, that is also easier to read and understand:

Request downloadRequest = new Request.Builder().url(fileUrl).get().build();

Response response = okHttpClient.newCall(downloadRequest).execute();
if (!response.isSuccessful()) {
  throw new IOException("Unexpected code: " + response);
}

File videoFile = ...
try (BufferedSource bufferedSource = response.body().source()) {
  BufferedSink bufferedSink = Okio.buffer(Okio.sink(videoFile));
  bufferedSink.writeAll(bufferedSource);
  bufferedSink.close();
}
@enwokoma

This comment has been minimized.

Copy link

enwokoma commented Jan 18, 2019

@saket. How fast can the download go when using this method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.