`
iloveoracle
  • 浏览: 118748 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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

    博客分类:
  • java
阅读更多
    <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-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;		}		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=""><br> 
 
1
1
分享到:
评论

相关推荐

    org.apache.commons.httpclient 远程下载文件

    在实际应用中,你可能需要考虑更多的细节,如错误处理、重试机制、进度显示、多线程下载等。此外,Apache HttpClient库已经被弃用,现在推荐使用Java 7及更高版本内置的`java.net.HttpURLConnection`或更现代的库如...

    java实现HttpClient异步请求资源的方法

    本篇文章将详细介绍如何使用Java的HttpClient实现异步请求资源。 首先,让我们了解什么是异步请求。在同步请求中,调用一个API或发送一个HTTP请求后,程序会等待响应返回,然后继续执行后续代码。而异步请求则不同...

    HttpClient介绍和使用文档

    HttpClient还支持重试机制、连接池管理、多线程请求等高级特性,使得在处理大量HTTP请求时更加高效和稳定。此外,HttpClient可以与其他Apache Commons库,如HttpCore、HttpComponents等配合使用,实现更复杂的网络...

    HttpClient包及例子

    例如,它支持多线程、连接池管理、重试策略、身份验证和压缩等高级特性。 使用HttpClient,你可以轻松地模拟GET请求。GET请求通常用于从服务器获取资源,比如网页或API数据。以下是一个简单的示例: ```java ...

    httpClient组合包.zip

    此外,HttpClient还支持异步操作,可以在多线程环境中高效地处理并发请求。 2. **httpcore-4.4.12.jar**:这是HttpClient的核心库,包含了HTTP协议的基本组件,如连接管理、请求和响应模型、编码器和解码器等。...

    httpClient完整请求Demo

    这通常在程序开始时完成,因为HttpClient是线程安全的,可以重复使用。 ```java CloseableHttpClient httpClient = HttpClients.createDefault(); ``` 2. **创建HttpGet或HttpPost对象**: 根据你的需求,你可以...

    HTTP异步工具包(HttpClient实现)

    3. **多线程处理回调**:在处理回调时,可以考虑使用线程池来避免主线程被阻塞,提高并发处理能力。 4. **错误处理**:在`failed`方法中,应正确处理异常,如重试策略、错误日志记录等。 四、总结 HttpClient提供...

    老罗http章例子

    1. **连接管理**:HttpClient支持多线程环境下的连接管理,可以设置连接池大小,有效控制并发连接数,提高性能。 2. **重定向处理**:HttpClient自动处理服务器返回的3xx状态码,根据Location头进行重定向。 3. **...

    HTTPClient4的典型小例子

    **HTTPClient4简介** ...**连接管理和多线程** HTTPClient4允许我们自定义连接管理器,以处理并发请求和连接池。`PoolingHttpClientConnectionManager`是常用的连接管理器,它可以复用TCP连接,提高性能: ```java ...

    一个面向对象风格的JavaHTTPClient

    Apache HttpClient库提供了丰富的API来构建复杂的HTTP请求,支持多线程、连接池和更强大的重试策略。以下是一个使用Apache HttpClient的例子: ```java CloseableHttpClient httpClient = HttpClients.create...

    httpClient 调用远程接口 获取数据到本地文件夹

    HttpClient支持多线程请求,可以使用ExecutorService来管理线程池。同时,注意防止对服务器的过度请求,遵守其速率限制政策,避免被封IP。 7. **安全性与身份验证**: 访问某些远程接口可能需要身份验证。...

    httpClient调用远程接口获取数据到本地文件夹

    为了提高效率,可以使用多线程并发处理多个请求,或者使用连接池管理HttpClient的连接,减少建立新连接的时间。 10. **测试与运行**: 提供一个测试类,可以直接运行以验证功能。测试类应包含初始化HttpClient、...

    HttpClient使用示例教程

    7. **连接管理器**:用于多线程应用,可设置最大连接数和每个主机的最大连接数,以及自动关闭过期连接。 8. **Cookie处理**:自动处理Set-Cookie头,并支持自定义Cookie策略。 9. **流控制**:优化了请求输出流和...

    HttpClient

    - **多线程**:HttpClient支持多线程执行请求,适合大量并发请求的场景。 - **连接管理**:HttpClient的HttpConnectionManager用于管理连接池,优化性能和资源利用。 - **重试策略**:可以通过设置重试处理器...

    Java爬虫小例子,爬取小网站,突破防盗链下载图片

    - **线程与异步处理**:为提高爬取效率,通常会使用多线程或异步处理技术,如Java的ExecutorService。 2. **网页解析**: - **CSS选择器**:通过CSS选择器定位网页元素,例如,用`doc.select("img")`找到所有图片...

    HttpClient.rar

    Apache HttpClient是一个成熟的HTTP客户端API,包含了许多高级特性,如连接管理、多线程支持、自定义编码解码等。 Apache HttpClient的使用通常涉及创建`CloseableHttpClient`实例,配置请求对象`HttpGet`或`...

    HttpClient中的client和server相互调用的两个例子

    但需注意线程安全问题,避免多个线程共享同一个HttpClient实例。 - 错误处理:正确处理异常,如网络中断、超时、重定向等。 - 安全性:在处理敏感信息时,确保使用HTTPS协议,设置SSL/TLS上下文。 6. **最佳实践*...

    httpClient官方实例

    `MultiThreadedExample_java.htm`可能包含有关如何在多线程环境中使用HttpClient的例子。在并发场景下,HttpClient能确保线程安全并有效利用资源。 4. **Cookie管理**: `CookieDemoApp_java.htm`可能会展示如何...

Global site tag (gtag.js) - Google Analytics