網路程式設計基礎,多執行緒下載

風的王子發表於2015-05-19

多執行緒下載圖片例子

package com.zcwfeng.java.test.netsocket;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class MutilDown {
    public static void main(String[] args) {
        final int DOWN_THREAD_NUM = 4;
        final String OUT_FILE_NAME = "mdown.jpg";

        InputStream[] isArr = new InputStream[DOWN_THREAD_NUM];
        RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];

        try {
            URL url = new URL("http://images.csdn.net/20150519/201.jpg");
            isArr[0] = url.openStream();
            long fileLen = getFileLength(url);
            System.out.println("資源大小" + fileLen);
            outArr[0] = new RandomAccessFile(OUT_FILE_NAME, "rw");
            // 建立一個與下載資源大小相同的空檔案
            for (int i = 0; i < fileLen; i++) {
                outArr[0].write(0);
            }
            // 每個執行緒下載的位元組數
            long numPerThread = fileLen / DOWN_THREAD_NUM;
            long left = fileLen % DOWN_THREAD_NUM;
            for (int i = 0; i < DOWN_THREAD_NUM; i++) {
                if (i != 0) {
                    isArr[i] = url.openStream();
                    outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");
                }
                if (i == DOWN_THREAD_NUM - 1) {
                    new DownloadThread(i * numPerThread, (i + 1) * numPerThread
                            + left, isArr[i], outArr[i]).start();;
                } else {
                    new DownloadThread(i * numPerThread,
                            (i + 1) * numPerThread, isArr[i], outArr[i]).start();
                }
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }

    private static long getFileLength(URL url) throws IOException {
        long length = 0;
        URLConnection conn = url.openConnection();
        long size = conn.getContentLength();
        length = size;
        return length;
    }
}
package com.zcwfeng.java.test.netsocket;

import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

/**
 * Description:<br/>
 * Copyright (C), 2005-2015,David<br/>
 * Thies program is protected by copyright<br/>
 * David. Program name<br/>
 * Date:2015年5月19日<br/>
 * 
 * @author David <br/>
 * @version 1.0
 *
 */
public class DownloadThread extends Thread {
    private final int BUFF_LEN = 32;
    private InputStream is;
    private long start;
    private long end;
    private RandomAccessFile raf;

    public DownloadThread() {
    }

    public DownloadThread(long start, long end, InputStream is,
            RandomAccessFile raf) {
        System.out.println(start + "------------>" + end);
        this.is = is;
        this.start = start;
        this.end = end;
        this.raf = raf;
    }

    @Override
    public void run() {
        super.run();
        try {
            is.skip(start);
            raf.seek(start);
            byte[] buff = new byte[BUFF_LEN];
            long contentLen = end - start;
            long times = contentLen / BUFF_LEN + 4;// 定義最多幾次讀取
            int hasRead = 0;
            for (int i = 0; i < times; i++) {
                hasRead = is.read(buff);

                if (hasRead <= 0) {
                    break;
                }
                raf.write(buff, 0, hasRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (raf != null) {
                    raf.close();
                }
                if (is != null) {
                    is.close();
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

相關文章