Okhttp多執行緒斷點續傳
目錄
1、斷點續傳相關定義
2、多執行緒下載實現方案
1、斷點續傳相關定義
1.1、斷點續傳:
記錄上次下載的位置,下次接著該位置繼續下載。
1.2、多執行緒下載:
根據目標下載檔案長度,分給多個執行緒同時下載。
1.3、多執行緒斷點續傳:
根據目標下載檔案長度,分給多個執行緒同時下載;每個執行緒在中斷下載時都記錄當前的下載位置,下次下載時接著該位置繼續下載(所有的執行緒下載完成,最終檔案也下載完成)。
2、斷點續傳相關技術方案
2.1、斷點續傳實現方案:
下載方面:
在http的header中新增rang欄位下載對應部分的內容。
/** * @param url下載連結 * @param startIndex 下載起始位置 * @param endIndex結束為止 * @param callback回撥 * @throws IOException */ public void downloadFileByRange(String url, long startIndex, long endIndex, Callback callback) throws IOException { // 建立一個Request // 設定分段下載的頭資訊。 Range:做分段資料請求,斷點續傳指示下載的區間。格式: Range bytes=0-1024或者bytes:0-1024 Request request = new Request.Builder().header("RANGE", "bytes=" + startIndex + "-" + endIndex) .url(url) .build(); doAsync(request, callback); }
檔案寫入方面:
使用RandomAccessFile類跳過已下載部分,然後開始寫入。
InputStream is = inputStream;// 獲取流 RandomAccessFile tmpAccessFile = new RandomAccessFile(mTmpFile, "rw");// 獲取前面已建立的檔案. tmpAccessFile.seek(finalStartIndex);// 檔案寫入的開始位置. /*將網路流中的檔案寫入本地*/ byte[] buffer = new byte[1024 << 2]; int length = -1; while ((length = is.read(buffer)) > 0) { tmpAccessFile.write(buffer, 0, length); }
2.2、多執行緒下載實現方案:
(1)計算每個執行緒下載的大小。
long blockSize = mFileLength / THREAD_COUNT
(2)開啟THREAD_COUNT個執行緒去下載檔案的對應部分。
for (int threadId = 0; threadId < THREAD_COUNT; threadId++) { long startIndex = threadId * blockSize; // 執行緒開始下載的位置 long endIndex = (threadId + 1) * blockSize - 1; // 執行緒結束下載的位置 if (threadId == (THREAD_COUNT - 1)) { // 如果是最後一個執行緒,將剩下的檔案全部交給這個執行緒完成 endIndex = mFileLength - 1; } download(startIndex, endIndex, threadId);// 開啟執行緒下載 }