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

java多线程下载

2015-11-10 22:30 483 查看
多线程下载是通过占有服务器资源来提高速度的。
每个线程应该下载一个文件的不同位置,假如现在有一个长度为10的资源,有三个线程,那么第一个线程下载的长度为012,第二个为345,第四个为6789
所以问题来了每个线程下载的长度是多少呢?
线程的id为0,1,2
每个线程下载的数量=总长度/线程数量
size=10/3
start:id*size
end:(id+1)*size-1
最后一个线程的结束位置为:总长度-1

package down;

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

public class Down {

static int threadCount = 3;
static String path = "http://192.168.21.1:8080/ok/ideaIU-14.1.3.exe";

/**
* @param args
*/
public static void main(String[] args) {
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
if(conn.getResponseCode()==200){
//第一次请求要下载的长度
int length = conn.getContentLength();
//应该从字符串中截取文件名称
File file = new File("ideaIU-14.1.3.exe");
//在下载之前生成临时文件,占位置
RandomAccessFile rdm = new RandomAccessFile(file, "rwd");
//给临时文件大小
rdm.setLength(length);
//关闭
rdm.close();
//计算每个线程应该下载的长度
int size = length/threadCount;
//为每个线程分配开始位置和结束位置
for (int i = 0; i <threadCount; i++) {
int start = i*size;
int end = (i+1)*size-1;
//最后一个线程的结束位置为总长度
if(i==threadCount-1){
end= length;
}
System.out.println(i+"线程下载区间"+start+"---"+end);
//每次都调用新的线程
new DownThread(start, end, i).start();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
//线程
class DownThread extends Thread{
private int start;
private int end;
private int threadId;

public DownThread(int start, int end, int threadId) {
this.start = start;
this.end = end;
this.threadId = threadId;
}

@Override
public void run() {
try {
//再次请求网络
URL url = new URL(Down.path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
conn.setConnectTimeout(5000);
//设置本次请求的文件的长度
conn.setRequestProperty("Range","bytes="+start+"-"+end);
//请求部分数据是206
if(conn.getResponseCode()==206){
//得到请求长度的文件输入流
InputStream is = conn.getInputStream();
byte[] b = new byte[1024];
int len = 0;
//记录每一次下载字节数
int totle =0;
//应该从字符串中截取文件名称
File file = new File("ideaIU-14.1.3.exe");
//拿到之前占位置那个文件,相当于输出流
RandomAccessFile rdm = new RandomAccessFile(file, "rwd");
//改变写入文件的开始位置
rdm.seek(start);
while((len=is.read(b))!=-1){
//每次读取流里的数据写到临时文件里
rdm.write(b, 0, len);
totle += len;
System.out.println(threadId+"线程"+"下载了"+totle);
}
rdm.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: