您的位置:首页 > 编程语言 > Java开发

Java多线程下载

2015-11-07 21:27 211 查看
我们可以使用多线程进行下载,这样可以提高下载的效率。这个在JavaSE和android系统中均适用。

效果:



附代码如下:

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

/**
* 多线程下载示例
* @author YUANYUAN
*
*/
public class Demo {
//下载所使用的线程数
private static int threadCount=3;

public static void main(String[] args) throws Exception{
//请求服务器的路径
String path="http://192.168.2.114:8080/sqlite.exe";
//构造URL地址
URL url=new URL(path);
//打开连接
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
//设置请求超时的时间
conn.setConnectTimeout(5000);
//设置请求方式
conn.setRequestMethod("GET");
//获取相应码
int code=conn.getResponseCode();
if (code==200) {//请求成功
//获取请求数据的长度
int length=conn.getContentLength();
//在客户端创建一个跟服务器文件大小相同的临时文件
RandomAccessFile raf=new RandomAccessFile("setup.exe", "rwd");
//指定临时文件的长度
raf.setLength(length);
raf.close();
//假设3个线程去下载资源
//平均每一个线程要下载的文件的大小
int blockSize=length/threadCount;
for (int threadId = 1; threadId <= threadCount; threadId++) {
//当前线程下载数据的开始位置
int startIndex=blockSize*(threadId-1);
//当前线程下载数据的结束位置
int endIndex=blockSize*threadId-1;
//确定最后一个线程要下载数据的最大位置
if (threadId==threadCount) {
endIndex=length;
}
//显示下载数据的区间
System.out.println("线程【"+threadId+"】开始下载:"+startIndex+"---->"+endIndex);
//开启下载的子线程
new DownloadThread(path, threadId, startIndex, endIndex).start();
}

}else{//请求失败
System.out.println("服务器异常,下载失败!");
}
}

/**
* 下载文件的子线程 每一个文件都下载对应的数据
* @author Administrator
*
*/
public static class DownloadThread extends Thread{
private String path;
private int threadId;
private int startIndex;
private int endIndex;

/**
* 构造方法
* @param path 下载文件的路径
* @param threadId 下载文件的线程
* @param startIndex 下载文件开始的位置
* @param endIndex 下载文件结束的位置
*/
public DownloadThread(String path, int threadId, int startIndex,
int endIndex) {
this.path = path;
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
}

@Override
public void run() {
//构造URL地址
try {
URL url = new URL(path);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//设置请求属性,请求部分资源
conn.setRequestProperty("Range", "bytes="+startIndex+"-"+endIndex);
int code=conn.getResponseCode();
if (code==206) {//下载部分资源,正常返回的状态码为206
InputStream is=conn.getInputStream();//已经设置了请求的位置,所以返回的是对应的部分资源
//构建随机访问文件
RandomAccessFile raf=new RandomAccessFile("setup.exe", "rwd");
//设置 每一个线程随机写文件开始的位置
raf.seek(startIndex);
//开始写文件
int len=0;
byte[] buffer=new byte[1024];
while((len=is.read(buffer))!=-1){//读取输入流
raf.write(buffer,0,len);//写文件
}
is.close();
raf.close();
//提示下载完毕
System.out.println("线程【"+threadId+"】下载完毕");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("线程【"+threadId+"】下载出现异常!!");
}

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: