Android下載-實時進度-斷點續傳

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/devallever/article/details/78349915

概述

帶顯示進度和斷點續傳的下載示例
使用Okhttp框架

思路

獲取下載文件的總大小,獲取本地文件,如果不存在,就下載,存在,就獲取文件的大小,
如果本地文件的大小與網絡上文件的大小,就提示下載完成。
如果本地文件大小 < 網絡上文件的大小,就跳過已下載的字節數開始下載。

具體實現

file = new File(path);
if (file.exists()){
    downloadedLength = file.length();
}
//獲取下載文件的總長度
long contentLength = getContentLength(url);
if (contentLength == 0 ){
    //獲取網絡文件大小失敗.
}else if (contentLength == downloadedLength){
    //下載完成.
}

獲取網絡文件大小

public static long getContentLength(String url) throws IOException {
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
                .url(url)
                .build();
    Response response = client.newCall(request).execute();
    if (response != null && response.isSuccessful()){
        long contentLength = response.body().contentLength();
        response.close();
        return contentLength;
    }
    return 0;
}
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    //斷點下載,跳過已下載的字節
                    .addHeader("RANGE", "bytes=" + downloadedLength + "-")
                    .url(url)
                    .build();
            //執行同步請求
            Response response = client.newCall(request).execute();
            if (response != null){
                inputStream = response.body().byteStream();
                saveFile = new RandomAccessFile(file, "rw");
                saveFile.seek(downloadedLength); //保存文件時跳過已下載的字節
                byte[] b = new byte[1024];
                int total = 0;
                int len;
                while ((len = inputStream.read(b)) != -1){
                    total += len;
                    saveFile.write(b,0,len);
                    int progress = (int)((total + downloadedLength) * 100 / contentLength);//progress代表百分比
                    publishProgress(progress);//調用onProgressUpdate()更新進度條
                }
                response.body().close();
            }

RandomAccessFile類

RandomAccessFile是用來訪問那些保存數據記錄的文件的,你就可以用seek( )方法來訪問記錄,並進行讀寫了。這些記錄的大小不必相同;但是其大小和位置必須是可知的。但是該類僅限於操作文件。

RandomAccessFile不屬於InputStream和OutputStream類系的。實際上,除了實現DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也實現了這兩個接口),它和這兩個類系毫不相干,甚至不使用InputStream和OutputStream類中已經存在的任何功能;它是一個完全獨立的類,所有方法(絕大多數都只屬於它自己)都是從零開始寫的。這可能是因爲RandomAccessFile能在文件裏面前後移動,所以它的行爲與其它的I/O類有些根本性的不同。總而言之,它是一個直接繼承Object的,獨立的類。

基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream結合起來,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件裏移動用的seek( ),以及判斷文件大小的length( )、skipBytes()跳過多少字節數。此外,它的構造函數還要一個表示以只讀方式(“r”),還是以讀寫方式(“rw”)打開文件的參數 (和C的fopen( )一模一樣)。它不支持只寫文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章