Last active
February 17, 2023 03:39
-
-
Save suweya/cc73abedcf8f9378f8a7179178106944 to your computer and use it in GitHub Desktop.
OkHttp download file by Okio
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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: