多线程下载

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

public class MultithreadsDownload {
    public static void main(String[] args) {
        final int DOWNLOAD_THREAD_NUM = 4;
        final String FILE_NAME = "download.jpg";
        InputStream[] is = new InputStream[DOWNLOAD_THREAD_NUM];
        RandomAccessFile[] raf = new RandomAccessFile[DOWNLOAD_THREAD_NUM];
        
        try {
            URL url = new URL("http://p.qpic.cn/ninja/0/ninja1393807134/0");
            for (int i=0; i<DOWNLOAD_THREAD_NUM; i++) {
                is[i] = url.openStream();
                raf[i] = new RandomAccessFile(FILE_NAME, "rw");
            }
            long filelen = getFileLength(url);
            System.out.println("The size of the file is : " + filelen);
            //create a empty final file
            for (int i=0; i<filelen; i++)
                raf[0].write(0);
            
            //compute the download size for per thread
            long numPerThread = filelen / DOWNLOAD_THREAD_NUM;
            long left = filelen % DOWNLOAD_THREAD_NUM;
            
            for (int i=0; i<DOWNLOAD_THREAD_NUM; i++) {
                if (i == DOWNLOAD_THREAD_NUM-1)
                    new DownloadThread(i*numPerThread, (i+1)*numPerThread + left,
                            is[i], raf[i]).start();
                else
                    new DownloadThread(i*numPerThread, (i+1)*numPerThread,
                            is[i], raf[i]).start();
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    public static long getFileLength(URL url) throws Exception
    {
        URLConnection conn = url.openConnection();
        long size = conn.getContentLengthLong();
        return size;
    }
}

class DownloadThread extends Thread {
    
    DownloadThread(long start, long end, InputStream is, RandomAccessFile raf)
    {
        System.out.println("Begin downloading : " + start + "--->" + end);
        this.start = start;
        this.end = end;
        this.is = is;
        this.raf = raf;
    }
    
    @Override
    public void run()
    {
        try {
            //seek the appropriate input location of the cur thread
            is.skip(start);
            //seek the appropriate location for writing
            raf.seek(start);
            byte[] buff = new byte[BUFF_SIZE];
            long contentLen = end - start;
            //Ensure the totally download
            long times = contentLen / BUFF_SIZE + 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 (Exception e)
        {
            e.printStackTrace();
        }
        finally {
            try {
                if (is != null)
                    is.close();
                if (raf != null)
                    raf.close();
            }catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    
    private final int BUFF_SIZE = 32;
    private long start;
    private long end;
    private InputStream is;
    private RandomAccessFile raf;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值