一、文件多线程下载步骤
1、 获取网络文件的长度,在android客户端生成一个与网络文件长度相等的空文件
2、 开启N条线程下载文件,计算每条线程负责下载的数据量
3、 依次创建,启动多条线程分别从网络文件的不同位置下载数据,并从本地文件的相同位置写入数据,要计算出每条线程从网络文件的什么位置开始下载数据,到什么位置结束下载
具体步骤
1、 打开HTTP协议的连接对象,为对象设置属性
//path为源路径
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
2、判断请求是否成功
if(conn.getResponseCode() == 200){
//步骤3 4 5 6
}
(以下步骤均在请求成功的基础上去实实现)
3、取得网络文件的长度
int length = conn.getContentLength();
4、随机文件访问类来生成一个与网络文件长度相等的本地文件
1>取得网络文件名称
String filename = path.substring(path.lastIndexOf("/")+1);//从最后一个"/"开始获取
2>创建文件
File file = new File(mubiao,filename); // mubiao指文件保存路径 filename为文件名称
3>随机文件访问
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
4>设置文件长度
accessFile.setLength(length);
accessFile.close();
5、计算每个线程负责下载的数据量
int block = length%threadsize == 0 ? length/threadsize :length/threadsize +1;
6、循环实现线程的下载
for(int threadid = 0 ;threadid
new DownloadThread(threadid,block,url,file).start();
}
7、创建线程类实现下载
private class DownloadThread extends Thread{
private int threadid;
private int block;
private URL url;
private File file;
public DownloadThread(int threadid, int block, URL url, File file) {
this.threadid=threadid;
this.block=block;
this.url=url;
this.file=file;
}
public void run(){
//计算该线程从网络文件的什么位置开始下载
int start = threadid * block ;
//下载到什么位置结束
int end= (threadid+1) * block-1 ;
try{
//建随机文件访问类对象
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
//指定从本地文件的某一个位置写入数据
accessFile.seek(start);
//请求网络文件某一个区域的数据
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
if(conn.getResponseCode() == 206){
InputStream instream = conn.getInputStream();
//循环读入数据
byte[] buffer = new byte[1024];
int len=0; //返回的读取到的长度
while((len = instream.read(buffer))!=-1){
//-------将数据写入本地文件
accessFile.write(buffer,0,len);
}
accessFile.close();
instream.close();
// System.out.println(threadid+1+"线程下载完成") ;
}
else{
// System.out.println(threadid+1+"线程下载失败") ;
}
}catch(Exception e){
e.printStackTrace();
}
}
}
重写线程的run方法
1>计算该线程从网络文件的什么位置开始下载
int start = threadid * block ;
2>下载到什么位置结束
int end= (threadid+1) * block-1 ;
3>建随机文件访问类对象
RandomAccessFile accessFile = new RandomAccessFile(file,"rwd");
4>指定从本地文件的某一个位置写入数据
accessFile.seek(start);
5>请求网络文件某一个区域的数据
1 得到HttpURLConnection对象,并设置属性
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
2 使用HTTP的Range头字段指定每条线程从文件的什么位置开始下载
下载到什么位置结束
conn.setRequestProperty("Range", "bytes="+start+"-"+end);
3 判断请求是否成功断点下载的返回码为206
if(conn.getResponseMethod()==206){
// 步骤4
}
4 得到输入流,通过输入流得到数据,将数据写入本地文件
InputStream instream = conn.getInputStream();
//循环读入数据
byte[] buffer = new byte[1024];
int len=0; //返回的读取到的长度
while((len = instream.read(buffer))!=-1){ //如果不为-1 说明数据没有读完
//-------将数据写入本地文件
accessFile.write(buffer,0,len);
}
accessFile.close();
instream.close();