根据多线程下载,我们知道,当我们在下载的时候如果遇到断电或者损坏,我们要从以前记录的数据文件接着下载,这样的下载就是多线程断点下载,,
-
具体代码体现
/**
* 多线程断点下载
* @author dandan
*
*/
public class Demo {
public static int threadCount = 3;
private static int runningthread = 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 {
//检查是否存在记录下载长度的文件,如果存在读取这个文件数据
//判断一下是否有断点存在,且不为空
File tempFile = new File(threadid+".txt");
if(tempFile.exists()&&tempFile.length()>0){
FileInputStream fis = new FileInputStream(tempFile);
byte[] temp = new byte[1024];
int leng = fis.read(temp);
String downloadlen = new String(temp,0,leng);
//吧downloadlen转换成Int类型
int downloadint = Integer.parseInt(downloadlen);
startid+=downloadint;//修改下载的真实的开始位置
fis.close();
}
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;
int total = 0;//已经下载的文件长度
byte[] buffer = new byte[1024];
while((len = is.read(buffer))!=-1){
RandomAccessFile file = new RandomAccessFile(threadid+".txt", "rwd");
//吧获取到的is流写到raf里面去
raf.write(buffer, 0, len);
total+=len;
file.write((""+total+startid).getBytes());
file.close();
}
is.close();
raf.close();
System.out.println("多线程下载完成: "+threadid);
File deletefile = new File(threadid+".txt");
deletefile.delete();//下载完成后 清楚下载记录
} catch (Exception e) {
e.printStackTrace();
}
finally{
//每个线程下载完毕以后,runningthread进行--操作
runningthread--;
if(runningthread==0){
for(int i=0;i<3;i++){
File file = new File(i+".txt");
file.delete();
System.out.println("文件下载完毕,清楚记录");
}
}
}
}
}
}
网友评论