线程可以理解为下载的通道,一个线程就是一个文件的下载通道,多线程也就是同时开启好几个下载通道。
首先我们先把tomcat服务器启动,然后把一个安装文件360.exe放到
G:\apache-tomcat-6.0.44\webapps\ROOT
路径下 ,用浏览器测试一下是否能访问成功,这里不做过多测试了,,
-
分析:
-
核心代码(此项目为java工程项目)MutilDownLoader
/**
* 多线程下载
* @author dandan
*
*/
public class Demo {
public static int threadCount = 3;
//链接服务器,获取服务器端文件,得到文件长度,在本地创建一个和服务器端大小相同的文件
public static void main(String[] args) throws Exception{
String path = "http://100.77.34.45:8686/360.exe";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.getContent();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code == 200){
//得到服务器端文件的长度
int length = conn.getContentLength();
System.out.println("文件总长度: "+length);
//在客户端创建一个临时文件
RandomAccessFile raf = new RandomAccessFile("steup.exe", "rwd");
//大小和服务器端文件大小一致
raf.setLength(length);
raf.close();
//利用多线程进行下载
//平均每个线程下载的文件大小
int blocksize = length/threadCount;
for(int threadid=1;threadid<=threadCount;threadid++){
//线程开始的位置
int startid = (threadid-1)*blocksize;
//线程结束的位置
int endid = threadid*blocksize-1;
if(threadid==threadCount){
endid=length;
}
System.out.println("线程: "+threadid+"下载: ----"+startid+"---->"+endid);
//主线程开启子线程
new downloadthread(threadid, startid, endid, path).start();
}
}
else {
System.out.println("服务器错误");
}
}
//下载文件的子线程 下载对应位置的文件
public static class downloadthread extends Thread{
private int threadid;
private int startid;
private int endid;
private String path;
/**
* @param threadid 线程id
* @param startid 线程开始的位置
* @param endid 线程结束的位置
* @param path 访问服务器的路径
*/
public downloadthread(int threadid, int startid, int endid, String path) {
super();
this.threadid = threadid;
this.startid = startid;
this.endid = endid;
this.path = path;
}
@Override
public void run() {
URL url;
try {
url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.getContent();
conn.setReadTimeout(5000);
conn.setRequestProperty("Range", "bytes= "+startid+"--"+endid);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();//200 ok 代表请求全部数据 //206 ok 代表请求部分数据
InputStream is = conn.getInputStream();
RandomAccessFile raf = new RandomAccessFile("steup.exe", "rwd");
//随机写文件从哪个位置开始写,定位文件位置
raf.seek(startid);
int len = 0;
byte[] buffer = new byte[1024];
while((len = is.read(buffer))!=-1){
//吧获取到的is流写到raf里面去
raf.write(buffer, 0, len);
}
is.close();
raf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
-
演示:
-
结果: