Java多執行緒下載的例子。

21ca發表於2009-08-12
直接看原始碼:
package test;

import java.io.BufferedInputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.CountDownLatch;

public class FileDownloadTest {
    private static final int THREAD_COUNT = 10;
    private CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
    private long completeLength = 0;
    private    long fileLength;
   
    //進行下載的執行緒
    class DownloadThread extends Thread {
        private URL url;
        private RandomAccessFile file;
        private long from;
        private long end;

        /**
         * @param url 下載的URL
         * @param file 下載完成之後儲存的檔案
         * @param from 當前執行緒對應檔案的起始位置
         * @param 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() {
            try {
                long pos = from;
                byte[] buf = new byte[1024];

                HttpURLConnection cn = (HttpURLConnection) url.openConnection();
               
                //因為有些網站根據它判斷是否是盜連結
                cn.setRequestProperty("Referer", "http://www.ibook8.com");
               
                //設定請求的起始和結束位置。
                cn.setRequestProperty("Range", "bytes=" + from + "-" + end);
               
                //如果請求錯誤,重試。
                if(cn.getResponseCode() != 200 && cn.getResponseCode() != 206){
                    System.out.println("Responce Code: " + cn.getResponseCode());
                    run();
                    return;
                }
                BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());
                int len;
                while ((len = bis.read(buf)) > 0) {
                    synchronized (file) {
                        file.seek(pos);
                        file.write(buf, 0, len);
                    }
                    pos += len;
                    completeLength += len;
                    System.out.println(completeLength * 100 / fileLength + "%");
                }
                cn.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
            latch.countDown();
        }
    }

    public void download(String address) throws Exception {
        URL url = new URL(address);
        URLConnection cn = url.openConnection();
        cn.setRequestProperty("Referer", "http://www.ibook8.com");
        fileLength = cn.getContentLength();
        long packageLength = fileLength / THREAD_COUNT;
        long leftLength = fileLength % THREAD_COUNT;
       
        RandomAccessFile file = new RandomAccessFile("sapco.rar", "rw");
       
        System.out.println(fileLength);
        //計算每個執行緒請求的起始位置和結束位置。
        long pos = 0;
        for (int i = 0; i < THREAD_COUNT; i++) {
            long endPos = pos + packageLength;
           
            if(leftLength > 0) {
                endPos++;
                leftLength--;
            }
            new DownloadThread(url, file, pos, endPos).start();
            pos = endPos;
        }
        latch.await();
    }

    public static void main(String[] args) throws Exception {
        long time = System.currentTimeMillis();
        new FileDownloadTest()
                .download("http://vip.ibook8.com/2008/7/sapco.rar");
        System.out.println(System.currentTimeMillis() - time);
    }

}

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10742815/viewspace-611955/,如需轉載,請註明出處,否則將追究法律責任。

相關文章