每条线程的下载位置计算:
Int block = 4;
Int start = threaid*block;
Int end =(threaid+1)*block-1;
第一步:获取数据总长,生成本地文件
通过观察浏览器返回的数据,可以看到Content-Length字段为数据的总长度
调用conn.getContentLength()可以获取数据总长。
获取文件名称:path.substring(path.lastIndexOf("/")+ 1);
path.lastIndexOf("/")取得最后一个"/"的位置编号(从0开始)
path.substring();减去的字符长度
生成本地文件:
RandomAccessFile(file,mode)
部分代码:
private voiddownload(String path, int threadsize) throws Exception {
URLdownpath = new URL(path);
HttpURLConnectionconn = (HttpURLConnection) downpath.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode()== 200){
int length = conn.getContentLength();//获取网络文件的长度
File file = new File(getFileName(path));//获取文件名
RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");//生成本地文件
accessFile.setLength(length);
accessFile.close();
。。。
}
}
第二步:开启线程,计算每条线程下载数据量
//计算每条线程负责下载的数据量
int block = length %threadsize == 0 ? length / threadsize : length / threadsize +1;
for(int threadid = 0; threadid < threadsize ; threadid++){
newDownloadThread(threadid, downpath, block, file).start();
}
第三步:开始下载
部分代码:
publicvoid run() {
int startposition = threadid * block;//从网络文件的什么位置开始下载数据
int endposition = (threadid+1) * block - 1;//下载到网络文件的什么位置结束
//指示该线程要从网络文件的startposition位置开始下载,下载到endposition位置结束
//Range:bytes=startposition-endposition
try{
RandomAccessFileaccessFile = new RandomAccessFile(file, "rwd");
accessFile.seek(startposition);//移动指针到文件的某个位置
HttpURLConnectionconn = (HttpURLConnection) downpath.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
//分段下载的请求码不是200而是206,使用if(conn.getResponseCode() == 200){会出错
//System.out.println(conn.getResponseCode());
conn.setRequestProperty("Range","bytes="+ startposition+ "-"+ endposition);
InputStreaminStream = conn.getInputStream();
byte[]buffer = new byte[1024];
intlen = 0;
while((len = inStream.read(buffer)) != -1 ){
accessFile.write(buffer,0, len);
}
//}
accessFile.close();
inStream.close();
System.out.println("第"+ (threadid+1)+ "线程下载完成");
}catch(Exception e) {
e.printStackTrace();
}
}