Java多線程斷點下載

來源:互聯網
上載者:User

標籤:abs   ati   資料   readline   儲存   資訊   位元組   ide   else   

public static class DownloadThread  extends Thread{        private int threadId;        private int startIndex;        private int endIndex;        private int lastPostion;        public DownloadThread(int threadId,int startIndex,int endIndex){            this.threadId = threadId;            this.startIndex = startIndex;            this.endIndex = endIndex;        }        @Override        public void run() {            synchronized (DownloadThread.class) {                runningTrheadCount = runningTrheadCount +1;//開啟一線程,線程數加1            }            //分段請求網路連接,分段儲存檔案到本地            try{                URL url = new URL(path);                HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();                openConnection.setRequestMethod("GET");                openConnection.setConnectTimeout(5*1000);                System.out.println("理論上下載:  線程:"+threadId+",開始位置:"+startIndex+";結束位置:"+endIndex);                //讀取上次下載結束的位置,本次從這個位置開始直接下載。                File file2 = new File(threadId+".txt");                if(file2.exists()){                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file2)));                    String lastPostion_str = bufferedReader.readLine();                    lastPostion = Integer.parseInt(lastPostion_str);//讀取檔案擷取上次下載的位置                    //設定分段下載的頭資訊。  Range:做分段資料請求用的。                    openConnection.setRequestProperty("Range", "bytes="+lastPostion+"-"+endIndex);//bytes:0-500:請求伺服器資源中0-500之間的位元組資訊  501-1000:                    System.out.println("實際下載1:  線程:"+threadId+",開始位置:"+lastPostion+";結束位置:"+endIndex);                    bufferedReader.close();                }else{                    lastPostion = startIndex;                    //設定分段下載的頭資訊。  Range:做分段資料請求用的。                    openConnection.setRequestProperty("Range", "bytes="+lastPostion+"-"+endIndex);//bytes:0-500:請求伺服器資源中0-500之間的位元組資訊  501-1000:                    System.out.println("實際下載2:  線程:"+threadId+",開始位置:"+lastPostion+";結束位置:"+endIndex);                }                System.out.println("getResponseCode"+openConnection.getResponseCode() );                if(openConnection.getResponseCode() == 206){//200:請求全部資源成功, 206代表部分資源請求成功                    InputStream inputStream = openConnection.getInputStream();                    //請求成功將流寫入本地檔案中,已經建立的佔位那個檔案中                    RandomAccessFile randomAccessFile = new RandomAccessFile(filename, "rw");                    randomAccessFile.seek(lastPostion);//設定隨機檔案從哪個位置開始寫。                    //將流中的資料寫入檔案                    byte[] buffer = new byte[1024];                    int length = -1;                    int total = 0;//記錄本次線程下載的總大小                    while((length= inputStream.read(buffer)) !=-1){                        randomAccessFile.write(buffer, 0, length);                        total = total+ length;                        //去儲存當前線程下載的位置,儲存到檔案中                        int currentThreadPostion = lastPostion + total;//計算出當前線程本次下載的位置                        //建立隨機檔案儲存當前線程下載的位置                        File file = new File(threadId+".txt");                        RandomAccessFile accessfile = new RandomAccessFile(file, "rwd");                        accessfile.write(String.valueOf(currentThreadPostion).getBytes());                        accessfile.close();                    }                    //關閉相關的流資訊                    inputStream.close();                    randomAccessFile.close();                    System.out.println("線程:"+threadId+",下載完畢");                    //當所有線程下載結束,刪除存放下載位置的檔案。                    synchronized (DownloadThread.class) {                        runningTrheadCount = runningTrheadCount -1;//標誌著一個線程下載結束。                        if(runningTrheadCount == 0 ){                            System.out.println("所有線程下載完成");                            for(int i =0 ;i< threadCount;i++){                                File file = new File(i+".txt");                                System.out.println(file.getAbsolutePath());                                file.delete();                            }                        }                    }                }            }catch (Exception e) {                e.printStackTrace();            }            super.run();        }    }

上面代碼主要做了4 件事 
1、設定分段下載的頭資訊; 
2、分段下載網路資源 
3、當中斷時把當前各個線程當前下載的位置分別儲存到一個臨時檔案中 
4、下載完成後把臨時檔案刪除 上面代碼中都給出了詳細的注釋

其中有一點要注意 
openConnection.setRequestProperty(“Range”, “bytes=”+lastPostion+”-“+endIndex); 
如果”bytes=格式不對的話會導致設定不成功,返回的將不是部分資源的返回碼 
另一個要說明的就是randomAccessFile.seek(startThread);是設定各個線程下載的開始位置 

 

Java多線程斷點下載

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.