Java多线程下载文件

openkk 8年前

文件下载采用多线程方式能够显著提高下载速度,关键点是设置线程的读取开始和结束位置。下面的代码,采用线程池启动10个线程来执行下载。

import java.io.BufferedInputStream;  import java.io.IOException;  import java.io.RandomAccessFile;  import java.net.HttpURLConnection;  import java.net.URL;  import java.net.URLConnection;  import java.util.concurrent.CountDownLatch;  import java.util.concurrent.ExecutorService;  import java.util.concurrent.Executors;      public class FileDownLoadTest {         private static final int TCOUNT = 10;      private CountDownLatch latch = new CountDownLatch(TCOUNT);     private long completeLength = 0;      private long fileLength;   /**    * @param args    * @throws Exception     */   public static void main(String[] args) throws Exception {        long begin = System.currentTimeMillis();    new FileDownLoadTest().download("http://test1.com");    System.out.println(System.currentTimeMillis() - begin);   }         public void download(String address) throws Exception{    ExecutorService service = Executors.newFixedThreadPool(TCOUNT);    URL url = new URL(address);    URLConnection cn = url.openConnection();    cn.setRequestProperty("Referer", "http://www.test.com");    fileLength = cn.getContentLength();    long packageLength = fileLength/TCOUNT;    long leftLength = fileLength%TCOUNT;    RandomAccessFile file = new RandomAccessFile("test.rar","rw");    //计算每个线程请求文件的开始和结束位置    long pos = 0;    long endPos = pos + packageLength;    for(int i=0; i<TCOUNT; i++){     if(leftLength >0){      endPos ++;      leftLength--;     }     service.execute(new DownLoadThread(url, file, pos, endPos));     pos = endPos;    }    latch.await();   }      class DownLoadThread implements Runnable{        private URL url;    private RandomAccessFile file;    private long from;    private long end;        DownLoadThread(URL url, RandomAccessFile file, long from, long end){     this.url = url;     this.file = file;     this.from = from;     this.end = end;    }            public void run() {     long pos = from;     byte[] buf = new byte[512];     try {      HttpURLConnection cn = (HttpURLConnection) url.openConnection();      cn.setRequestProperty("Range", "bytes=" + from + "-" + end);      if(cn.getResponseCode() != 200 && cn.getResponseCode()!=206){       run();       return;      }      BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());      int len ;      while((len = bis.read(buf)) != -1){       synchronized(file){        file.seek(pos);        file.write(buf, 0, len);       }       pos += len;       completeLength +=len;       System.out.println(completeLength * 100 /fileLength + "%");      }      cn.disconnect();      latch.countDown();     } catch (IOException e) {      e.printStackTrace();           }    }   }  }
转自:http://blog.csdn.net/lb85858585/article/details/7304304