首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 服务器 > Apache >

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

2012-10-25 
使用Apache HttpClient实现多线程下载的小例子span stylecolor: #000000网上类似的文章很多,参考了

使用Apache HttpClient实现多线程下载的小例子
    <span style="color: #000000;">网上类似的文章很多,参考了很多人的,大部分人都是用urlconnection写的。</span>
<h3><span style="color: #0000ff;">原理一:http多线程下载原理</span></h3>1、发送一个含有rang头的head请求,如果返回状态码为206,则允许多线程下载
?
<h3><span style="color: #0000ff;">原理二:多线程下载原理</span></h3>1、使用httpclient的head请求获取请求文件的信息
2、发送一个rang的head请求判断是否允许多线程下载
3、通过主任务创建多个分段下载线程,分段下载文件,然后用java的随机读写文件类保存下载的内容
?
等有时间了再添加内容吧,先简单写这么多
<h4><span style="color: #ff0000;">调度功能代码片段</span></h4>

/** * 开始下载 * @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-lengthheader[] 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;}httphead.abort();}/** * 启动多个下载线程 * @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);thread.adddownloadlistener(listener);thread.start();threads.add(thread);startposition = endposition + 1;//此处加 1,从结束位置的下一个地方开始请求endposition += perthreadlength;} while (startposition < contentlength);}
<h4><span style="color: #ff0000;">?分段下载线程代码片段:</span></h4>
/** * 现在过程代码 */public void run() {if(downloadtask.getdebug()){system.out.println("start:" + startposition + "-" +endposition);}httpclient httpclient = new defaulthttpclient();try {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 &amp;&amp; !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();} catch (exception e) {e.printstacktrace();} finally {//触发下载完成事件firedowncompleted(new downloadthreadevent(this, endposition));if(downloadtask.getdebug()){system.out.println("end:" + startposition + "-" +endposition);}httpclient.getconnectionmanager().shutdown();}}
<h4>?附件说明:</h4>1、download.jar为编译好的可运行程序
2、download.zip为eclipse项目文件
3、运行截图<br><img src="http://dl.iteye.com/upload/attachment/423030/ecf09679-708a-3351-9b60-9697ff2f6fd8.jpg" alt="使用Apache HttpClient实现多线程上载的小例子"><br>?
 

热点排行