Java簡單多執行緒斷點下載

weixin_33763244發表於2017-11-03

使用多執行緒下載檔案可以更快完成檔案的下載,多執行緒下載檔案之所以快,是因為其搶佔的伺服器資源多。如:假設伺服器同時最多服務100個使用者,在伺服器中一條執行緒對應一個使用者,100條執行緒在計算機中並非併發執行,而是由CPU劃分時間片輪流執行,如果A應用使用了99條執行緒下載檔案,那麼相當於佔用了99個使用者的資源,假設一秒內CPU分配給每條執行緒的平均執行時間是10ms,A應用在伺服器中一秒內就得到了990ms的執行時間,而其他應用在一秒內只有10ms的執行時間。就如同一個水龍頭,每秒出水量相等的情況下,放990毫秒的水肯定比放10毫秒的水要多。

 


  1. XML/HTML 程式碼複製內容到剪貼簿  
  2.       
  3. package cn.mzba.download;        
  4.         
  5. import java.io.File;        
  6. import java.io.InputStream;        
  7. import java.io.RandomAccessFile;        
  8. import java.net.HttpURLConnection;        
  9. import java.net.URL;        
  10.         
  11. public class MulThreadDownloader {        
  12.         
  13.     /**        
  14.      * 1、首先獲取網路上的內容,然後獲取檔案的長度,標題。 然後在本地上生成一個同樣大小並且同名的檔案。 2、執行執行緒        
  15.      * 3、執行緒首先定義一個隨機輸入流,用來下載檔案同步寫入本地檔案 設定Range從指定的開始位置-結束位置下載檔案。        
  16.      * 4、獲取伺服器返回的輸入流寫入檔案。        
  17.      *         
  18.      */        
  19.     public static void main(String[] args) throws Exception {        
  20.         String path = "http://www.wo...56c.jpg";        
  21.         new MulThreadDownloader().download(path, 3);        
  22.         System.in.read();        
  23.     }        
  24.         
  25.     public void download(String path, int threadsize) throws Exception {        
  26.         URL url = new URL(path);        
  27.         HttpURLConnection conn = (HttpURLConnection) url.openConnection();        
  28.         conn.setRequestMethod("GET");        
  29.         conn.setConnectTimeout(5 * 1000);        
  30.         int length = conn.getContentLength(); // 獲取檔案長度        
  31.         File localfile = new File(getFileName(path));        
  32.         RandomAccessFile file = new RandomAccessFile(localfile, "rwd");        
  33.         file.setLength(length);        
  34.         file.close();        
  35.         // 計算每條執行緒下載的資料長度        
  36.         int block = length % threadsize == 0 ? length / threadsize : length        
  37.                 / threadsize + 1;        
  38.         for (int i = 0; i < threadsize; i++) {        
  39.             new DownLoadThread(i, url, block, localfile).start();        
  40.         }        
  41.     }        
  42.         
  43.     private final class DownLoadThread extends Thread {        
  44.         
  45.         private int threadid;        
  46.         private URL url;        
  47.         private int block;        
  48.         private File localfile;        
  49.         
  50.         public DownLoadThread(int threadid, URL url, int block, File localfile) {        
  51.             this.threadid = threadid;        
  52.             this.block = block;        
  53.             this.url = url;        
  54.             this.localfile = localfile;        
  55.         }        
  56.         
  57.         @Override        
  58.         public void run() {        
  59.             int startposition = threadid * block; // 從網路檔案的什麼位置開始下載資料        
  60.             int endposition = startposition + block - 1; // 下載到檔案的什麼位置結束        
  61.             RandomAccessFile file;        
  62.             try {        
  63.                 file = new RandomAccessFile(localfile, "rwd");        
  64.                 file.seek(startposition);        
  65.                 HttpURLConnection conn = (HttpURLConnection) url        
  66.                         .openConnection();        
  67.                 conn.setRequestMethod("GET");        
  68.                 conn.setConnectTimeout(5 * 1000);        
  69.                 conn.setRequestProperty("Range", "bytes=" + startposition + "-"        
  70.                         + endposition);        
  71.                 InputStream is = conn.getInputStream();        
  72.                 byte[] buffer = new byte[1024];        
  73.                 int len = 0;        
  74.                 while ((len = is.read(buffer)) != -1) {        
  75.                     file.write(buffer, 0, len);        
  76.                 }        
  77.                 is.close();        
  78.                 file.close();        
  79.                 System.out.println("執行緒id" + threadid + "已經下載完成");        
  80.             } catch (Exception e) {        
  81.                 // TODO Auto-generated catch block        
  82.                 e.printStackTrace();        
  83.             }        
  84.         
  85.             super.run();        
  86.         }        
  87.         
  88.     }        
  89.         
  90.     public static String getFileName(String path) {        
  91.         return path.substring(path.lastIndexOf("/") + 1);        
  92.     }        
  93. }    

 


     本文轉自06peng 51CTO部落格,原文連結:http://blog.51cto.com/06peng/962470,如需轉載請自行聯絡原作者




相關文章