java多线程下载文件

来源:互联网 发布:抑郁 知乎 编辑:程序博客网 时间:2024/05/16 07:07
  1. import java.io.File;  
  2. import java.io.InputStream;  
  3. import java.io.RandomAccessFile;  
  4. import java.net.HttpURLConnection;  
  5. import java.net.URL;  
  6.   
  7. public class MulThreadDownload {  
  8.     public static void main(String[] args) throws Exception {  
  9.         String path = "http://192.168.1.100:8080/Hello/Big.exe";  
  10.         new MulThreadDownload().download(path, 3);  
  11.     }  
  12.   
  13.     /** 
  14.      * 下载文件 
  15.      *  
  16.      * @param path 
  17.      *            网络文件路径 
  18.      * @param threadSize 
  19.      *            线程数 
  20.      * @throws Exception 
  21.      */  
  22.     private void download(String path, int threadSize) throws Exception {  
  23.         URL url = new URL(path);  
  24.         HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
  25.         connection.setRequestMethod("GET");  
  26.         connection.setConnectTimeout(5000);  
  27.         if (connection.getResponseCode() == 200) {  
  28.             int length = connection.getContentLength();// 获取网络文件长度  
  29.             File file = new File(getFileName(path));  
  30.             // 在本地生成一个长度与网络文件相同的文件  
  31.             RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");  
  32.             accessFile.setLength(length);  
  33.             accessFile.close();  
  34.   
  35.             // 计算每条线程负责下载的数据量  
  36.             int block = length % threadSize == 0 ? length / threadSize : length  
  37.                     / threadSize + 1;  
  38.             for (int threadId = 0; threadId < threadSize; threadId++) {  
  39.                 new DownloadThread(threadId, block, url, file).start();  
  40.             }  
  41.         } else {  
  42.             System.out.println("download fail");  
  43.         }  
  44.     }  
  45.   
  46.     private class DownloadThread extends Thread {  
  47.   
  48.         private int threadId;  
  49.         private int block;  
  50.         private URL url;  
  51.         private File file;  
  52.   
  53.         public DownloadThread(int threadId, int block, URL url, File file) {  
  54.             this.threadId = threadId;  
  55.             this.block = block;  
  56.             this.url = url;  
  57.             this.file = file;  
  58.         }  
  59.   
  60.         @Override  
  61.         public void run() {  
  62.             int start = threadId * block; // 计算该线程从网络文件什么位置开始下载  
  63.             int end = (threadId + 1) * block - 1// 计算下载到网络文件什么位置结束  
  64.             try {  
  65.                 RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");  
  66.                 accessFile.seek(start);  //从start开始  
  67.   
  68.                 HttpURLConnection connection = (HttpURLConnection) url  
  69.                         .openConnection();  
  70.                 connection.setRequestMethod("GET");  
  71.                 connection.setConnectTimeout(5000);  
  72.                 //设置获取资源数据的范围,从start到end  
  73.                 connection.setRequestProperty("Range""bytes=" + start + "-"  
  74.                         + end);  
  75.                 //注意多线程下载状态码是 206  不是200  
  76.                 if (connection.getResponseCode() == 206) {  
  77.                     InputStream inputStream = connection.getInputStream();  
  78.                     byte[] buffer = new byte[1024];  
  79.                     int len = 0;  
  80.                     while ((len = inputStream.read(buffer)) != -1) {  
  81.                         accessFile.write(buffer, 0, len);  
  82.                     }  
  83.                     accessFile.close();  
  84.                     inputStream.close();  
  85.                 }  
  86.                 System.out.println("第" + (threadId + 1) + "条线程已经下载完成");  
  87.             } catch (Exception e) {  
  88.                 e.printStackTrace();  
  89.             }  
  90.         }  
  91.     }  
  92.   
  93.     /** 
  94.      * 获取文件名称 
  95.      *  
  96.      * @param path 
  97.      *            网络文件路径 
  98.      * @return 
  99.      */  
  100.     private String getFileName(String path) {  
  101.         return path.substring(path.lastIndexOf("/") + 1);  
  102.     }  
  103. }  
0 0