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

說(shuō)明:
生成多個(gè)線程去服務(wù)器下載文件,服務(wù)器幾乎同一時(shí)間處理每個(gè)線程,這樣就會(huì)更快的下好文件,但注意并不是開(kāi)的線程越多,速度越快。
文件的存儲(chǔ)是有序的,必須保證下載的有序性,我們可以對(duì)需要下載的文件進(jìn)行數(shù)據(jù)分塊,這樣每次訪問(wèn)的就可以不是完整的文件了。http協(xié)議有一個(gè)range字段,可以設(shè)置數(shù)據(jù)訪問(wèn)的區(qū)域位置,java中有RandomAccessfile類(lèi)可以我們按需要去讀寫(xiě)改某個(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請(qǐng)求
            connection.setRequestMethod("GET");
            //設(shè)置鏈接網(wǎng)絡(luò)的超時(shí)時(shí)間
            connection.setConnectTimeout(8000);
            //獲取返回碼
            int code =connection.getResponseCode();
            if (code==200) {
                //代表請(qǐng)求成功
                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;
                    }
                    //開(kāi)啟線程去服務(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代表請(qǐng)求全部資源成功,206代表請(qǐng)求部分資源成功
                     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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容