首先來看一下多線程下載的原理。多線程下載就是將同一個網絡上的原始文件根據線程個數分成均等份,然后每個單獨的線程下載對應的一部分,然后再將下載好的文件按照原始文件的順序“拼接”起來就構
成了完整的文件了。這樣就大大提高了文件的下載效率。對于文件下載來說,多線程下載是必須要考慮的環(huán)節(jié)。

      多線程下載大致可分為以下幾個步驟:

       一.獲取服務器上的目標文件的大小
              顯然這一步是需要先訪問一下網絡,只需要獲取到目標文件的總大小即可。目的是為了計算每個線程應該分配的下載任務。

      二. 在本地創(chuàng)建一個跟原始文件同樣大小的文件
             在本地可以通過RandomAccessFile 創(chuàng)建一個跟目標文件同樣大小的文件,該api 支持文件任意位置的讀寫操作。這樣就給多線程下載提供了方便,每個線程只需在指定起始和結束腳標范圍內寫數據即可。

      三.計算每個線程下載的起始位置和結束位置
             我們可以把原始文件當成一個字節(jié)數組,每個線程只下載該“數組”的指定起始位置和指定結束位置之間的部分。在第一步中我們已經知道了“數組”的總長度。因此只要再知道總共開啟的線程的個數就好計算每個線程要下載的范圍了。每個線程需要下載的字節(jié)個數(blockSize)=總字節(jié)數(totalSize)/線程數(threadCount)。       假設給線程按照0,1,2,3...n 的方式依次進行編號,那么第n 個線程下載文件的范圍為:
               起始腳標startIndex=n*blockSize。
              結束腳標endIndex=(n-1)*blockSize-1。
            考慮到totalSize/threadCount 不一定能整除,因此對已最后一個線程應該特殊處理,最后一個線程的起始腳標計算公式不變,但是結束腳標為endIndex=totalSize-1即可。
     四.開啟多個子線程開始下載
            在子線程中實現讀流操作,將conn.getInputStream()讀到RandomAccessFile中。