package multiThreadDownload;
import java.io.*;
import java.net.*;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.logging.*;
public class HttpTask extends Task {
private static final HttpClient httpClient;
private static final Log logger = LogFactory.getLog(HttpTask.class);
static {
MultiThreadedHttpConnectionManager connectionManager =
new MultiThreadedHttpConnectionManager();
connectionManager.getParams().setDefaultMaxConnectionsPerHost(20);
httpClient = new HttpClient(connectionManager);
}
private URL url;
private File destination;
private int threadCounts;
private long contentLength;
private volatile boolean stop = false;
private int workerCompleted = 0;
private HttpTaskWorker[] workers;
private RandomAccessFile store;
private DownloadListener listener;
public HttpTask(String url, String dest, int threadCounts)
{
if (url == null || dest == null) {
throw new NullPointerException();
}
if (threadCounts <= 0) {
throw new IllegalArgumentException();
}
try {
this.url = new URL(url);
if (!this.url.getProtocol().equals("http")) {
throw new IllegalArgumentException("Unsupported URL Scheme");
}
this.destination = new File(dest);
if (!(destination.exists() && destination.isDirectory()
&& destination.canWrite())) {
throw new IllegalArgumentException("Illegal destination folder");
}
this.threadCounts = threadCounts;
workers = new HttpTaskWorker[threadCounts];
}
catch (MalformedURLException ex) {
throw new IllegalArgumentException("Illegal Resource URL");
}
}
protected long getResourceContentLen() throws HttpException, IOException
{
HeadMethod head = new HeadMethod(url.toString());
head.setFollowRedirects(false);
int statusCode = httpClient.executeMethod(head);
if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY){
String recentUrl = head.getResponseHeader("Location").getValue();
logger.info("URL redirection: " + recentUrl);
this.url = new URL(url.getProtocol(),
url.getHost(),
url.getPort(),
recentUrl);
head = new HeadMethod(url.toString());
statusCode = httpClient.executeMethod(head);
}
if (statusCode == HttpStatus.SC_OK) {
destination = new File(destination,
new File(url.getPath()).getName());
store = new RandomAccessFile(destination, "rw");
logger.info("File " + destination.getName() + " Created.");
listener.onProgress("File " + destination.getName() + " Created.");
return head.getResponseContentLength();
}
else {
throw new UnsupportedOperationException();
}
}
public void start() {
String msg = "Starting to download URL: " + url.toString();
logger.info(msg);
listener.onProgress(msg);
try {
contentLength = getResourceContentLen();
msg = "Resource Content Length is " + contentLength;
logger.info(msg);
listener.onProgress(msg);
listener.onGetContentLength(destination.getName(), contentLength);
long chunk = contentLength / threadCounts;
long startPos = 0;
long endPos;
for (int i = 0; i < threadCounts; i++)
{
endPos = startPos + chunk;
if (i == threadCounts - 1) {
endPos = contentLength;
}
workers[i] = new HttpTaskWorker(
"Worker Thread #" + (i + 1),
startPos, endPos - 1);
workers[i].start();
startPos = endPos;
}
}
catch(Exception ex) {
logger.fatal(ex);
ex.printStackTrace();
}
}
public void stop() {
stop = true;
}
public void resume(){
stop = false;
for (int i = 0; i < workers.length; i++) {
if (!workers[i].isDone()) {
workers[i] = new HttpTaskWorker(
"Worker Thread #" + (i+1),
workers[i].startPos,
workers[i].endPos, workers[i].complete);
workers[i].start();
}
}
}
public synchronized void onWorkerComplete() {
workerCompleted++;
if (workerCompleted == threadCounts) {
String msg = "!!!!!!Download Completed.!!!!!!";
logger.info(msg);
listener.onProgress(msg);
try {
store.close();
}
catch(IOException ioe) {
logger.error(ioe);
}
}
}
protected synchronized void saveChunk(byte[] buf, int offset, int len, long absPos)
throws IOException {
store.seek(absPos);
store.write(buf, offset, len);
}
public void addDownloadListener(DownloadListener listener) {
this.listener = listener;
}
/**
* Http Resource download worker thread.
*/
protected class HttpTaskWorker extends Thread {
/**
* bytes range start position.
*/
private long startPos;
/**
* bytes range end position.
*/
private long endPos;
/**
* bytes number completed.
*/
private long complete;
/**
* create Http resource download worker thread with specified bytes range
* and already completed bytes.
* @param name worker thread name
* @param startPos bytes range start position.
* @param endPos bytes range end position.
* @param complete bytes number completed.
*/
public HttpTaskWorker(String name, long startPos, long endPos, long complete) {
super(name);
this.startPos = startPos;
this.endPos = endPos;
this.complete = complete;
String msg = getName() + " Worker Created: startPos = "
+ startPos
+ " endPos = "
+ endPos
+ " Complete = "
+ complete;
logger.info(msg);
listener.onProgress(msg);
}
/**
* create Http resource download worker thread with specified bytes range
*
* @param name
* @param startPos
* @param endPos
*/
public HttpTaskWorker(String name, long startPos, long endPos) {
this(name, startPos, endPos, 0);
}
private boolean isDone() {
return endPos - startPos == complete;
}
public void run() {
GetMethod get = createGetMethod();
try {
InputStream in;
byte buf[] = new byte[4096];
int bytesRead;
int bytesNeedToSave;
int chunkSize = (int)(endPos - startPos + 1);
while (!stop && complete < chunkSize) {
httpClient.executeMethod(get);
in = get.getResponseBodyAsStream();
while ((bytesRead = in.read(buf)) != -1 && complete < chunkSize) {
String msg = getName() + "Bytes read " + bytesRead + " bytes";
logger.debug(msg);
//listener.onProgress(msg);
bytesNeedToSave = (int)(bytesRead + complete > chunkSize ? chunkSize - complete : bytesRead);
if (bytesNeedToSave > 0)
listener.onReadChunk(this.getName(), bytesNeedToSave);
saveChunk(buf, 0, bytesNeedToSave, startPos + complete);
complete += bytesNeedToSave;
}
String msg = getName() + " Bytes Completed: " + complete + " bytes";
logger.info(msg);
listener.onProgress(msg);
}
}
catch(HttpException he) {
logger.error(he);
}
catch(IOException ioe) {
logger.error(ioe);
listener.onProgress(getName() + " " + ioe.getMessage());
}
finally {
get.releaseConnection();
String msg = getName() + " " + "Http Connection released.";
logger.info(msg);
listener.onProgress(msg);
}
String msg= getName() + " Download complete. :)";
logger.info(msg);
listener.onProgress(msg);
onWorkerComplete();
}
protected GetMethod createGetMethod() {
GetMethod get = new GetMethod(url.toString());
get.addRequestHeader("Accept", "*/*");
get.addRequestHeader("User-Agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)");
get.addRequestHeader("Pragma", "no-cache");
get.addRequestHeader("Cache-Control","no-cache");
get.addRequestHeader("Connection", "close");
if (startPos + complete > 0) {
String bytesRange = String.valueOf(startPos + comple
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
Java多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Http协议的断点续传.rarJava多线程与线程安全实践-基于Htt
资源推荐
资源详情
资源评论
收起资源包目录
Java多线程与线程安全实践-基于Http协议的断点续传.rar (73个子文件)
Java多线程与线程安全实践-基于Http协议的断点续传
MultiThreadDownload
multiThreadDownload
ConsoleDownloader.class 2KB
DownloadEvent.class 304B
HttpTask.class 7KB
ConsoleDownloader.java 1KB
NewTaskDialog.java 4KB
GUIDownloadListener$2.class 1KB
HttpTask.java 8KB
BatchTaskAction.class 2KB
NewTaskDialog.class 5KB
DownloadAdapter.java 362B
DownloadListener.java 831B
NewTaskAction.class 2KB
ConsoleDownloadListener.java 416B
BatchTaskDialog.java 5KB
GUIDownloader.java 5KB
ExitAction.class 604B
ExitAction.java 477B
BatchTaskAction.java 896B
GUIDownloader$1.class 1KB
ConsoleDownloadListener.class 970B
NewAboutDialog.class 2KB
DeleteTaskAction.java 435B
GUIDownloader$2.class 727B
DownloadException.java 89B
AboutAction.java 465B
DownloadException.class 319B
BatchTaskDialog$1.class 2KB
icons
checked.gif 892B
unchecked.gif 877B
disabledCount.gif 860B
disabledSaveAs.gif 883B
Thumbs.db 24KB
count.gif 860B
rightArrow.gif 999B
save.gif 891B
disabledSave.gif 871B
new.gif 874B
disabledAbout.gif 950B
disabledAddBook.gif 893B
about.gif 968B
saveAs.gif 893B
addBook.gif 893B
disabledNew.gif 862B
open.gif 877B
disabledRemoveBook.gif 911B
disabledOpen.gif 861B
removeBook.gif 911B
NewTaskAction.java 776B
DeleteTaskAction.class 1KB
BatchTaskDialog.class 6KB
NewTaskDialog$1.class 2KB
GUIDownloadListener$3.class 1KB
HttpTask$HttpTaskWorker.class 5KB
Task.class 325B
DownloadEvent.java 197B
DownloadListener.class 354B
GUIDownloader.class 7KB
DownloadAdapter.class 946B
AboutAction.class 1KB
GUIDownloadListener.class 5KB
Task.java 167B
GUIDownloader$3.class 847B
NewAboutDialog.java 2KB
GUIDownloadListener.java 4KB
GUIDownloadListener$1.class 1KB
lib
commons-httpclient-3.0.1.jar 273KB
commons-logging-adapters-1.1.jar 20KB
commons-logging-1.1.jar 52KB
commons-logging-api-1.1.jar 44KB
commons-codec-1.3.jar 46KB
.classpath 2KB
.project 395B
swt-win32-3138.dll 308KB
共 73 条
- 1
资源评论
职场程序猿
- 粉丝: 6149
- 资源: 3706
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- (源码)基于C语言的系统服务框架.zip
- (源码)基于Spring MVC和MyBatis的选课管理系统.zip
- (源码)基于ArcEngine的GIS数据处理系统.zip
- (源码)基于JavaFX和MySQL的医院挂号管理系统.zip
- (源码)基于IdentityServer4和Finbuckle.MultiTenant的多租户身份认证系统.zip
- (源码)基于Spring Boot和Vue3+ElementPlus的后台管理系统.zip
- (源码)基于C++和Qt框架的dearoot配置管理系统.zip
- (源码)基于 .NET 和 EasyHook 的虚拟文件系统.zip
- (源码)基于Python的金融文档智能分析系统.zip
- (源码)基于Java的医药管理系统.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功