成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Android多線程斷點(diǎn)下載簡單實(shí)現(xiàn)

ad6623 / 1344人閱讀

摘要:多線程斷點(diǎn)下載原理獲取目標(biāo)文件的大小在本地創(chuàng)建一個(gè)相同大小的文件并計(jì)算每個(gè)線程需要下載的起始位置及大小然后分配至每個(gè)線程獨(dú)立下載全部下載完畢則自動(dòng)合并實(shí)現(xiàn)步驟查看并計(jì)算目標(biāo)文件的大小文件總長度為設(shè)置目標(biāo)文件在本地的映射開啟子線程并分配下載任

HTTP多線程斷點(diǎn)下載

原理:獲取目標(biāo)文件的大小,在本地創(chuàng)建一個(gè)相同大小的文件,并計(jì)算每個(gè)線程需要下載的起始位置及大小,然后分配至每個(gè)線程獨(dú)立下載,全部下載完畢則自動(dòng)合并.

實(shí)現(xiàn)步驟

查看并計(jì)算目標(biāo)文件的大小

URL url = new URL(mPath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int code = connection.getResponseCode();
if (code == 200) {
    int length = connection.getContentLength();
    System.out.println("文件總長度為:" + length);

設(shè)置目標(biāo)文件在本地的映射

RandomAccessFile raf = new RandomAccessFile(
        Environment.getExternalStorageDirectory().getAbsolutePath()
                +"/"+getDownlaodName(mPath), "rw");
raf.setLength(length);

開啟子線程并分配下載任務(wù)

int blokeSize = length / mTotalCount;
System.out.println("每一塊大小為:" + blokeSize);
runningThreadCount = mTotalCount;
for (int threadid = 0; threadid < mTotalCount; threadid++) {
    int startPosition = threadid * blokeSize;
    int endPosition = (threadid + 1) * blokeSize - 1;
    //最后一個(gè)線程應(yīng)該下載至末尾
    if (threadid == mTotalCount - 1) {
        endPosition = length - 1;
    }
    System.out.println("線程編號(hào):" + threadid + ""
            + ",下載范圍:" + startPosition + "~~" + endPosition);
    //開啟下載子線程
    new DownloadThread(threadid, startPosition, endPosition).start();

子線程中的具體邏輯

public void run() {
    System.out.println("線程"+threadid+"開始運(yùn)行了");
    try{
        //讀存有歷史下載進(jìn)度的文件,判斷是否已經(jīng)下載過
        File finfo=new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                +"/"+mTotalCount + getDownlaodName(mPath)+threadid+".txt");
        if (finfo.exists()&&finfo.length()>0) {
            //獲取文件輸入流
            FileInputStream fis=new FileInputStream(finfo);
            //讀取緩沖
            BufferedReader br=new BufferedReader(new InputStreamReader(fis));
            //得到文件內(nèi)容
            String lasrposition=br.readLine();
            //轉(zhuǎn)化為int值
            int intlastposition=Integer.parseInt(lasrposition);
            lastLoadSize=intlastposition-startPosition;
            startPosition=intlastposition;
            fis.close();
        }
        URL url=new URL(mPath);
        HttpURLConnection conn=(HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        System.out.println("線程實(shí)際下載:"+threadid+",范圍:"+startPosition
                +"~~"+endPosition);
        //設(shè)置http請(qǐng)求頭部參數(shù)
        conn.setRequestProperty("Range", "bytes="+startPosition+"-"+endPosition);
        int code=conn.getResponseCode();
        //206代表請(qǐng)求部分?jǐn)?shù)據(jù)成功
        if (code==206) {
            //拿到鏈接返回的輸入流
            InputStream is=conn.getInputStream();
            //指向要寫的文件(abc.exe)
            RandomAccessFile raf=new RandomAccessFile(
                    Environment.getExternalStorageDirectory().getAbsolutePath()
                            +"/"+getDownlaodName(mPath), "rw");
            //指定文件開始寫的位置
            raf.seek(startPosition);
            //下載緩沖區(qū),越大下載越快,對(duì)硬盤損耗越小,但是越容易丟失數(shù)據(jù)
            byte[] buffer=new byte[1024*1024];
            int len=-1;
            int total=0;//當(dāng)前線程本次下載數(shù)據(jù)總量
            while ((len=is.read(buffer))!=-1) {
                raf.write(buffer,0,len);
                total+=len;
                //將每次更新的數(shù)據(jù)同步到底層硬盤
                RandomAccessFile inforaf=new RandomAccessFile(
                        Environment.getExternalStorageDirectory().getAbsolutePath()
                        +"/"+mTotalCount +getDownlaodName(mPath)+threadid+".txt","rwd");
                //保存當(dāng)前線程下載到什么位置
                inforaf.write(String.valueOf(startPosition+total).getBytes());
                inforaf.close();
            }
            is.close();
            raf.close();
            System.out.println("線程"+threadid+"下載完畢");

        }
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //同步代碼塊,保證同時(shí)間僅有一個(gè)線程執(zhí)行此區(qū)塊代碼
        synchronized (MainActivity.class) {
            runningThreadCount--;
            if (runningThreadCount<=0) {
                System.out.println("多線程下載完畢");
                for (int i = 0; i 

備注:如果不使用斷點(diǎn)下載,只需要將判斷和存儲(chǔ)歷史下載信息的邏輯刪除即可。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64908.html

相關(guān)文章

  • 線程系列之學(xué)習(xí)線程下載的基本原理和基本用法(1)

    摘要:多線程下載原理及步驟在本地創(chuàng)建一個(gè)大小跟服務(wù)器文件相同大小的臨時(shí)文件。在這里在介紹一個(gè)有關(guān)多線程下載的中的相關(guān)類隨機(jī)文件訪問類只有才有搜尋方法,而這個(gè)方法也只適用于文件。利用這個(gè)類才能實(shí)現(xiàn)文件的多線程下載。 多線程下載在我們生活中非常常見,比如迅雷就是我們常用的多線程的下載工具,當(dāng)然還有斷點(diǎn)續(xù)傳,斷點(diǎn)續(xù)傳我們?cè)谙乱还?jié)來講,android手機(jī)端下載文件時(shí)也可以用多線程下載,我們這里是在j...

    darry 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<