多線程斷點(diǎn)續(xù)傳

說明:
生成多個(gè)線程去服務(wù)器下載文件,服務(wù)器幾乎同一時(shí)間處理每個(gè)線程,這樣就會更快的下好文件,但注意并不是開的線程越多,速度越快。
文件的存儲是有序的,必須保證下載的有序性,我們可以對需要下載的文件進(jìn)行數(shù)據(jù)分塊,這樣每次訪問的就可以不是完整的文件了。http協(xié)議有一個(gè)range字段,可以設(shè)置數(shù)據(jù)訪問的區(qū)域位置,java中有RandomAccessfile類可以我們按需要去讀寫改某個(gè)區(qū)域。

代碼:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class MutiDownload {
    private static String DOWNLOAD_PATH="http://s1.music.126.net/download/osx/NeteaseMusic_1.4.3_452_web.dmg";
    private static int THREAD_COUNT=3;
    private static final String fileName="/Users/August/Desktop/NeteaseMusic_1.4.3_452_web.dmg";
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            HttpURLConnection connection=(HttpURLConnection) new URL(DOWNLOAD_PATH).openConnection();
            //設(shè)置參數(shù),發(fā)送GET請求
            connection.setRequestMethod("GET");
            //設(shè)置鏈接網(wǎng)絡(luò)的超時(shí)時(shí)間
            connection.setConnectTimeout(8000);
            //獲取返回碼
            int code =connection.getResponseCode();
            if (code==200) {
                //代表請求成功
                RandomAccessFile raf=new RandomAccessFile(fileName, "rw");
                long filesize;
                filesize=connection.getContentLength();
                long eachsize = filesize/THREAD_COUNT;
                raf.setLength(filesize);
                raf.close();
                for (int i = 0; i < THREAD_COUNT; i++) {
                    long startIndex=i*eachsize;
                    long endIndex=(i+1)*eachsize;
                    if (i==THREAD_COUNT-1) {
                        endIndex=filesize-1;
                    }
                    //開啟線程去服務(wù)器下載
                    DownloadThread downloadThread=new DownloadThread(DOWNLOAD_PATH,fileName,i,startIndex,endIndex);
                    
                }
            }else{
                
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            
        }
        
        
        }
}
class DownloadThread extends Thread{
    private String url;
    private String fileName;
    private int threadId;
    private long startIndex;
    private long endIndex;
    private HttpURLConnection connection;
    private RandomAccessFile raf;
    private InputStream inputStream;
    public DownloadThread(String url,String fileName,int threadId,long startIndex,long endIndex) {
        this.endIndex=endIndex;
        this.fileName=fileName;
        this.startIndex=startIndex;
        this.threadId=threadId;
        this.url=url;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        
            try {
                 connection = (HttpURLConnection) new URL(url + "?ts=" + System.currentTimeMillis()).openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(8000);
                //告訴服務(wù)器每個(gè)線程的下載位置與結(jié)束位置
                connection.setRequestProperty("RANGE", "bytes=" + startIndex + "-" + endIndex);
                int code =connection.getResponseCode();
                if (code==206) {   //200代表請求全部資源成功,206代表請求部分資源成功
                     inputStream=connection.getInputStream();
                     raf=new RandomAccessFile(fileName, "rw");
                    raf.seek(startIndex);//
                    int len=-1;
                    long total=0;
                    byte[]buffer=new byte[1024];  //1kb
                    while ((len=inputStream.read(buffer))!=-1) {
                        total+=len;
                        System.out.println("線程"+threadId+":"+total);
                        raf.write(buffer,0,len);
                        
                    }
                }
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } finally {
                try{
                if (connection!=null) {
                    connection.disconnect();
                }
                if (raf!=null) {
                    raf.close();
                }
                if (inputStream!=null) {
                    inputStream.close();
                }
                }catch(Exception e2){
                    e2.printStackTrace();
                }
                
            }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,923評論 18 139
  • 文章出處我們先一起簡單回顧下它的基本原理。http://www.lxweimin.com/p/cfae9a28529...
    呂中宜閱讀 1,472評論 1 11
  • 安卓多線程斷點(diǎn)續(xù)傳 非WIFI暫停,手動暫停。 話不多說,上圖,上demo。 喜歡的訂閱關(guān)注一下,每周會更新3-5...
    linux那些事閱讀 2,095評論 0 3
  • 最近迷上了王菲的《單行道》,單曲循環(huán),聽著她的歌聲,就像在聽自己的人生。 從宿舍通往圖書館的那條道路,就像通往人生...
    雙林木兮閱讀 339評論 0 4
  • 在生活中,經(jīng)常回聽見有人說,我不羨慕轟轟烈烈的愛情,我只想找一個(gè)普普通通的男朋友,兩個(gè)人建立一個(gè)溫馨的小家,過著平...
    文熊熊閱讀 454評論 0 0