多线程下载原理

来源:互联网 发布:天视6.3监控软件 编辑:程序博客网 时间:2024/06/10 17:51

(1)首先获取网络文件的长度,然后在Android客户端中生成一个与网络文件长度相同的本地文件

(2)开启N条线程下载文件,计算每条线程负责下载的数据量,公式如下:int  block=文件长度%N==0? 文件长度/N:文件长度/N+1

(3)开启多条线程分别从网络文件的不同位置下载数据,并从本地文件相同的位置写入数据,要求计算出每条线程从网络文件的什么位置开始下载数据,到什么位置结束

首先建一个Java项目

package cn.itcast.download;
public class MulThreadDownload {


/**
* @param args
*/
public static void main(String[] args) throws Exception{
String path = "http://192.168.1.100:8080/videonews/QQWubiSetup.exe";
new MulThreadDownload().download(path,3);   //把类的对象给new出来,并传入下载路径和线程数
}
/**
* 下载文件
* @param path网络文件路径
* @throws Exception对外声明抛出例外
*/
private void download(String path,int threadsize) throws Exception {
URL url=new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();    //打开http协议的链接对象
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");      //在本地生成一个与网络文件长度相同的本地文件
     /*第一个参数:传入文件,第二个参数:r/rw/rws:对文件的内容和元数据的每个更新都同步写到基础存储设备
/rwd:对文件的每个更新都同步写入到基础存储设备*/
accessFile.setLength(length);    //将网络文件的长度设置进去
accessFile.close();
int block = length%threadsize==0 ? length/threadsize:length/threadsize+1;  //计算每条线程负责下载的数据量
for(int threadid = 0;threadid<threadsize;threadid++){
new DownloadThread(threadid,block,url,file).start();   //开启线程,传入线程id,数据量,路径,要下载的文件

}
}else{
System.out.println("下载失败");
}

}
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) {   //为DownloadThread类创建出构造器
this.threadid=threadid;
this.block=block;
this.url=url;
this.file=file;

}
public void run() {    //线程运行起来后要调用此方法
int start = threadid*block;   //计算该线程从网络文件的什么位置开始下载
int end = threadid*block-1;   //下载到网络文件的什么位置结束
try {
RandomAccessFile accessFile =new RandomAccessFile(file,"rwd");      //在本地生成一个与网络文件长度相同的本地文件
     /*第一个参数:传入文件,第二个参数:r/rw/rws:对文件的内容和元数据的每个更新都同步写到基础存储设备
/rwd:对文件的每个更新都同步写入到基础存储设备*/
accessFile.seek(start);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();    //打开http协议的链接对象
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);
inStream.close();
}
accessFile.close();
}
System.out.println("第"+(threadid+1)+"条线程已经下载完成");
} catch (IOException e) {

e.printStackTrace();
}
}

}
private String getFilename(String path) {
path.substring(path.lastIndexOf("/")+1);
return null;
}
}

0 0
原创粉丝点击