多线程断点下载文件

所谓多线程断点下载 :就是当某个文件下了一部分后突然断电了,或者下载程序暂停了,再次运行下载 可以继续下载,而不是重新下载 的一个执行过程。

基本模拟了迅雷下载的原理

本次功能用java实现 :

利用txt文件记录下载的状态 如果在安卓端的话 可以改成用数据库记录下载状态

本程序可以扩展为具有良好用户体验的 下载程序

package mutiDownload;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
* 多线程断点下载文件
*
* @author Administrator
*
*/
public class BreakpointDoloadDemo {

public static int threadcount = 3;
public static int threadRunning = 3;



public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub

// 获取服务器上的文件长度,在本地创建一个和服务器上的文件一样大的临时文件
String pathString = "http://192.168.1.84:8091/androidServer/test.mkv";
URL url = new URL(pathString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
int code = connection.getResponseCode();
if (code == 200) { // 请求成功
int length = connection.getContentLength();
System.out.println("文件长度:" + length);
RandomAccessFile ref = new RandomAccessFile("test.mkv", "rwd");
// 指定创建的临时文件的长度
ref.setLength(length);
ref.close();

int blocksize = length / threadcount;
for (int threadId = 1; threadId <= threadcount; threadId++) {
int startIndex = (threadId - 1) * blocksize; // 线程开始位置
int endIndex = threadId * blocksize - 1;
if (threadId == threadcount) {
endIndex = length;
}
System.out.println("线程" + threadId + "下载---" + startIndex
+ "-->" + endIndex);
new Downhread(threadId, startIndex, endIndex, pathString)
.start();
;

}
} else {
System.out.println("服务器错误");
}

}

/**
* 下载文件子线程
*
* @author Administrator
*
*/
public static class Downhread extends Thread {
private int threadId;
private int startIndex;
private int endIndex;
private String path;

/**
*
* @param threadId
* 线程id
* @param startIndex
* 线程下载的开始位置
* @param endIndex
* @param path
* 下载文件在服务器上的位置
*/
public Downhread(int threadId, int startIndex, int endIndex, String path) {
super();
this.threadId = threadId;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.path = path;
}

@Override
public void run() {
// TODO Auto-generated method stub
// super.run();
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);
int downloadInt=Integer.parseInt(downloadLen);
startIndex=downloadInt; //修改下载的真实开始位置
}




URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET");
connection.setRequestProperty("Range", "bytes=" + startIndex
+ "-" + endIndex);

System.out.println("线程真实下载位置:" + threadId + "startIndex:" + startIndex+"-->"+endIndex);
int code = connection.getResponseCode();
System.out.println("code:" + code);
// if(code==200){ //请求成功
//
// }
InputStream is = connection.getInputStream();
RandomAccessFile raf = new RandomAccessFile("test.mkv", "rwd");
// 写文件的时候指定从哪个位置开始写
raf.seek(startIndex);

int len = 0;
byte[] buffer = new byte[1024];
int total = 0; // 已经下载的数据长度
// File file=new File(threadId+".txt"); //作用:记录当前线程下载的数据长度

while ((len = is.read(buffer)) != -1) {
RandomAccessFile file = new RandomAccessFile(threadId
+ ".txt", "rwd");
raf.write(buffer, 0, len);
total += len;
//System.out.println("线程:" + threadId + "total:" + total);
file.write(String.valueOf(total+startIndex).getBytes()); //记录下载的位置
file.close();
}
is.close();
raf.close();
System.out.println("线程:" + threadId + "下载完毕了...");

// File delfile =new File(threadId+ ".txt");
// delfile.delete(); //当线程下载完毕后清除记录文件

} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
threadRunning--;

if(threadRunning==0){ //所有线程执行完毕
for(int i=0;i<=3;i++){
File file =new File(i+ ".txt");
file.delete();
}
System.out.println("文件下载完毕,删除所有记录文件");
}
}
}
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值