天天看点

使用Apache HttpClient实现多线程下载的小例子

网上类似的文章很多,参考了很多人的,大部分人都是用urlconnection写的。

1、发送一个含有rang头的head请求,如果返回状态码为206,则允许多线程下载

1、使用httpclient的head请求获取请求文件的信息

2、发送一个rang的head请求判断是否允许多线程下载

3、通过主任务创建多个分段下载线程,分段下载文件,然后用java的随机读写文件类保存下载的内容

(等有时间了再添加内容吧,先简单写这么多)

java代码

/**  

 * 开始下载  

 * @throws exception  

 */  

public void startdown() throws exception{   

    httpclient httpclient = new defaulthttpclient();   

    try {   

        //获取下载文件信息   

        getdownloadfileinfo(httpclient);   

        //启动多个下载线程   

        startdownloadthread();   

        //开始监视下载数据   

        monitor();   

    } catch (exception e) {   

        throw e;   

    } finally {   

        httpclient.getconnectionmanager().shutdown();   

    }   

}   

 * 获取下载文件信息  

private void getdownloadfileinfo(httpclient httpclient) throws ioexception,   

        clientprotocolexception, exception {   

    httphead httphead = new httphead(url);   

    httpresponse response = httpclient.execute(httphead);   

    //获取http状态码   

    int statuscode = response.getstatusline().getstatuscode();   

    if(statuscode != 200) throw new exception("资源不存在!");   

    if(getdebug()){   

        for(header header : response.getallheaders()){   

            system.out.println(header.getname()+":"+header.getvalue());   

        }   

    //content-length   

    header[] headers = response.getheaders("content-length");   

    if(headers.length > 0)   

        contentlength = long.valueof(headers[0].getvalue());   

    httphead.abort();   

    httphead = new httphead(url);   

    httphead.addheader("range", "bytes=0-"+(contentlength-1));   

    response = httpclient.execute(httphead);   

    if(response.getstatusline().getstatuscode() == 206){   

        acceptranges = true;   

 * 启动多个下载线程  

 * @throws ioexception  

 * @throws filenotfoundexception  

private void startdownloadthread() throws ioexception,   

        filenotfoundexception {   

    //创建下载文件   

    file file = new file(localpath);   

    file.createnewfile();   

    randomaccessfile raf = new randomaccessfile(file, "rw");   

    raf.setlength(contentlength);   

    raf.close();   

    //定义下载线程事件实现类   

    downloadthreadlistener listener = new downloadthreadlistener() {   

        public void afterperdown(downloadthreadevent event) {   

            //下载完一个片段后追加已下载字节数   

            synchronized (object) {   

                downloadtask.this.receivedcount += event.getcount();   

            }   

        public void downcompleted(downloadthreadevent event) {   

            //下载线程执行完毕后从主任务中移除   

            threads.remove(event.gettarget());   

            if(getdebug()){   

                system.out.println("剩余线程数:"+threads.size());   

    };   

    //不支持多线程下载时   

    if (!acceptranges) {   

        if(getdebug()){   

            system.out.println("该地址不支持多线程下载");   

        //定义普通下载   

        downloadthread thread = new downloadthread(url, 0, contentlength, file, false);   

        thread.adddownloadlistener(listener);   

        thread.start();   

        threads.add(thread);   

        return;   

    //每个请求的大小   

    long perthreadlength = contentlength / threadcount + 1;   

    long startposition = 0;   

    long endposition = perthreadlength;   

    //循环创建多个下载线程   

    do{   

        if(endposition >= contentlength)   

            endposition = contentlength - 1;   

        downloadthread thread = new downloadthread(url, startposition, endposition, file);   

        startposition = endposition + 1;//此处加 1,从结束位置的下一个地方开始请求   

        endposition += perthreadlength;   

    } while (startposition < contentlength);   

}  

使用Apache HttpClient实现多线程下载的小例子
使用Apache HttpClient实现多线程下载的小例子
使用Apache HttpClient实现多线程下载的小例子

 * 现在过程代码  

public void run() {   

    if(downloadtask.getdebug()){   

        system.out.println("start:" + startposition + "-" +endposition);   

        httpget httpget = new httpget(url);   

        if(isrange){//多线程下载   

            httpget.addheader("range", "bytes="+startposition+"-"+endposition);   

        httpresponse response = httpclient.execute(httpget);   

        int statuscode = response.getstatusline().getstatuscode();   

        if(downloadtask.getdebug()){   

            for(header header : response.getallheaders()){   

                system.out.println(header.getname()+":"+header.getvalue());   

            system.out.println("statuscode:" + statuscode);   

        if(statuscode == 206 || (statuscode == 200 && !isrange)){   

            inputstream inputstream = response.getentity().getcontent();   

            //创建随机读写类   

            randomaccessfile outputstream = new randomaccessfile(file, "rw");   

            //跳到指定位置   

            outputstream.seek(startposition);   

            int count = 0;byte[] buffer=new byte[1024];   

            while((count = inputstream.read(buffer, 0, buffer.length))>0){   

                outputstream.write(buffer, 0, count);   

                //触发下载事件   

                fireafterperdown(new downloadthreadevent(this,count));   

            outputstream.close();   

        httpget.abort();   

        e.printstacktrace();   

        //触发下载完成事件   

        firedowncompleted(new downloadthreadevent(this, endposition));   

            system.out.println("end:" + startposition + "-" +endposition);   

1、download.jar为编译好的可运行程序

2、download.zip为eclipse项目文件

3、运行截图

使用Apache HttpClient实现多线程下载的小例子

download.jar (928.1 kb)

下载次数: 44

download.zip (832.5 kb)

下载次数: 70

继续阅读