国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

ad6623 / 1336人閱讀

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

HTTP多線程斷點下載

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

實現(xiàn)步驟

查看并計算目標文件的大小

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è)置目標文件在本地的映射

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;
    //最后一個線程應(yīng)該下載至末尾
    if (threadid == mTotalCount - 1) {
        endPosition = length - 1;
    }
    System.out.println("線程編號:" + threadid + ""
            + ",下載范圍:" + startPosition + "~~" + endPosition);
    //開啟下載子線程
    new DownloadThread(threadid, startPosition, endPosition).start();

子線程中的具體邏輯

public void run() {
    System.out.println("線程"+threadid+"開始運行了");
    try{
        //讀存有歷史下載進度的文件,判斷是否已經(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("線程實際下載:"+threadid+",范圍:"+startPosition
                +"~~"+endPosition);
        //設(shè)置http請求頭部參數(shù)
        conn.setRequestProperty("Range", "bytes="+startPosition+"-"+endPosition);
        int code=conn.getResponseCode();
        //206代表請求部分數(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ū),越大下載越快,對硬盤損耗越小,但是越容易丟失數(shù)據(jù)
            byte[] buffer=new byte[1024*1024];
            int len=-1;
            int total=0;//當前線程本次下載數(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");
                //保存當前線程下載到什么位置
                inforaf.write(String.valueOf(startPosition+total).getBytes());
                inforaf.close();
            }
            is.close();
            raf.close();
            System.out.println("線程"+threadid+"下載完畢");

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

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

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64908.html

相關(guān)文章

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

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

    darry 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<