Java多線程下載文件

openkk 12年前發布 | 42K 次閱讀 Java Java開發

文件下載采用多線程方式能夠顯著提高下載速度,關鍵點是設置線程的讀取開始和結束位置。下面的代碼,采用線程池啟動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();

        }
    }
}

}</pre>轉自:http://blog.csdn.net/lb85858585/article/details/7304304</span>

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!