Android學習記錄(5)—在java中學習多線程下載之斷點續傳②

來源:互聯網
上載者:User

在上一節中我們學習了在java中學習多線程下載的基本原理和基本用法,我們並沒有講多線程的斷點續傳,那麼這一節我們就接著上一節來講斷點續傳,斷點續傳的重要性不言而喻,可以不用重複下載,也可以節省時間,實現斷點續傳的關鍵在於怎麼記錄下載的進度和怎麼標識,現在我們就來講一下。

簡言之就是:為每個線程開闢一個檔案,分別來記錄每個線程的下載進度,在每個線程下載之前判斷這個標記檔案是否存在,如果存在讀取相應檔案裡面的資料,並將下載檔案的線程設定到相應的下載點即可。

這一節的代碼和上一節其實差不多,僅僅就是多了標記下載進度的一段代碼。現在我們一起來看看吧。

這段代碼就是在下載線程中去判斷每個線程的記錄下載進度的檔案是否存在,如果存在則讀取裡面的進度。並把startIndex的值設定到相應的資料。

接著就是上述標記下載進度的檔案是怎麼產生的,在哪裡產生的呢?代碼如下:

這個記錄檔案的產生就是在下載的檔案寫入到本地的過程中來標記產生的。

最後就是在所有線程結束後,把標記每個線程下載進度的檔案刪除。記住:實在所有線程結束後一起刪除,並不是在每個下載線程運行完後就刪除。為什麼是所有線程完後再刪除呢?自己考慮吧,我就不解釋了!<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PGltZyBzcmM9"http://www.bkjia.com/uploadfile/Collfiles/20140104/20140104132929233.jpg" alt="\">

這就是刪除標記檔案的操作。到這裡的解釋就完了,懂了嗎?

現在我把完整代碼貼出來,跟大家共用,代碼如下:

package net.loonggg.test;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.io.RandomAccessFile;import java.net.HttpURLConnection;import java.net.URL;public class MutilDownloader {// 開啟的線程的個數public static final int THREAD_COUNT = 3;public static int runningThread = 3;// 記錄正在啟動並執行下載檔案的線程數public static void main(String[] args) throws Exception {String path = "檔案";// 1、串連伺服器,擷取一個檔案,擷取檔案的長度,在本地建立一個大小跟伺服器檔案大小一樣的臨時檔案URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");int code = conn.getResponseCode();if (code == 200) {// 伺服器返回的資料的長度,實際就是檔案的長度int length = conn.getContentLength();System.out.println("----檔案總長度----" + length);// 在用戶端本地建立出來一個大小跟伺服器端檔案一樣大小的臨時檔案RandomAccessFile raf = new RandomAccessFile("temp.apk", "rwd");// 指定建立的這個檔案的長度raf.setLength(length);// 關閉rafraf.close();// 假設是3個線程去下載資源// 平均每一個線程下載的檔案的大小int blockSize = length / THREAD_COUNT;for (int threadId = 1; threadId <= THREAD_COUNT; threadId++) {// 第一個線程開始下載的位置int startIndex = (threadId - 1) * blockSize;int endIndex = threadId * blockSize - 1;if (threadId == THREAD_COUNT) {endIndex = length;}System.out.println("----threadId---" + "--startIndex--"+ startIndex + "--endIndex--" + endIndex);new DownloadThread(path, threadId, startIndex, endIndex).start();}}}/** * 下載檔案的子線程,每一個線程下載對應位置的檔案 *  * @author loonggg *  */public static class DownloadThread extends Thread {private int threadId;private int startIndex;private int endIndex;private String path;/** * @param path *            下載檔案在伺服器上的路徑 * @param threadId *            線程id * @param startIndex *            線程下載的開始位置 * @param endIndex *            線程下載的結束位置 */public DownloadThread(String path, int threadId, int startIndex,int endIndex) {this.path = path;this.threadId = threadId;this.startIndex = startIndex;this.endIndex = endIndex;}@Overridepublic void run() {try {// 檢查是否存在記錄下載長度的檔案,如果存在讀取這個檔案的資料File tempFile = new File(threadId + ".txt");if (tempFile.exists() && tempFile.length() > 0) {FileInputStream fis = new FileInputStream(tempFile);byte[] temp = new byte[1024 * 10];int leng = fis.read(temp);// 已經下載的長度String downloadLen = new String(temp, 0, leng);int downloadInt = Integer.parseInt(downloadLen);startIndex = downloadInt;fis.close();}URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");// 重要:請求伺服器下載部分的檔案 指定檔案的位置conn.setRequestProperty("Range", "bytes=" + startIndex + "-"+ endIndex);conn.setConnectTimeout(5000);// 從伺服器請求全部資源的狀態代碼200 ok 如果從伺服器請求部分資源的狀態代碼206 okint code = conn.getResponseCode();System.out.println("---code---" + code);InputStream is = conn.getInputStream();// 已經設定了請求的位置,返回的是當前位置對應的檔案的輸入資料流RandomAccessFile raf = new RandomAccessFile("temp.apk", "rwd");// 隨機寫檔案的時候從哪個位置開始寫raf.seek(startIndex);// 定位檔案int len = 0;byte[] buffer = new byte[1024];int total = 0;// 記錄已經下載的資料的長度while ((len = is.read(buffer)) != -1) {RandomAccessFile recordFile = new RandomAccessFile(threadId+ ".txt", "rwd");// 記錄每個線程的下載進度,為斷點續傳做標記raf.write(buffer, 0, len);total += len;recordFile.write(String.valueOf(startIndex + total).getBytes());recordFile.close();}is.close();raf.close();System.out.println("線程:" + threadId + "下載完畢了!");} catch (Exception e) {e.printStackTrace();} finally {runningThread--;if (runningThread == 0) {// 所有的線程已經執行完畢for (int i = 1; i <= THREAD_COUNT; i++) {File file = new File(i + ".txt");file.delete();}}}}}}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.