多线程下载原理

来源:互联网 发布:java反转单链表递归 编辑:程序博客网 时间:2024/05/21 12:44

步骤:

1>、首先从web服务器获取网络文件的长度,然后再Android客户端生成一个与网络文件长度相等的本地文件

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

文件长度/N:文件长度/N+1

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


int threadid 0,1,2;//开启线程的编号

int block;//每条线程负责下载的数据量

int start = threadid *block;//每条线程下载数据的开始位置

int end = (threadid+1) * block - 1;//每条线程下载数据的结束位置。

本应用为简单的java应用:



代码:




public class MulThreadDownload {


public static void main(String[] args) throws Exception {
String path = "http://192.168.0.12:8080/videonews/install_flash_player_ax_KB370315.exe";
   new MulThreadDownload().download(path,3);
}


private void download(String path,int threadsize) throws Exception {
// TODO Auto-generated method stub
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
System.out.println("333333333333333"+conn.getResponseCode());
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++) {
new DownloadThread(threadid,block,url,file).start();
}
}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) {
// TODO Auto-generated constructor stub
this.threadid = threadid;
this.block = block;
this.url = url;
this.file = file;
}
@Override
public void run() {
// TODO Auto-generated method stub
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 iStream = conn.getInputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len=iStream.read(buffer))!=-1) {
accessfile.write(buffer, 0, len);
}
accessfile.close();
iStream.close();
}
System.out.println("第"+(threadid+1)+"条线程下载完成");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


private String getFileName(String path) {
// TODO Auto-generated method stub

return path.substring(path.lastIndexOf("/")+1);
}
}

这样,一个简单的文件下载器就做好了。

注:本程序为简单的java应用,非安卓应用

0 0
原创粉丝点击