您的位置:首页 > 移动开发 > Android开发

android多线程下载以及断点续传

2014-08-29 14:51 375 查看
使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。如:假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而是由CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,假设一秒内CPU分配给每条线程的平均执行时间是10ms,A应用在服务器中一秒内就得到了990ms的执行时间,而其他应用在一秒内只有10ms的执行时间。就如同一个水龙头,每秒出水量相等的情况下,放990毫秒的水

肯定比放10毫秒的水要多。

多线程下载的实现过程:

1>首先得到下载文件的长度,然后设置本地文件

的长度。

HttpURLConnection.getContentLength();

RandomAccessFile file = new RandomAccessFile("QQWubiSetup.exe","rwd");

file.setLength(filesize);//设置本地文件的长度

2>根据文件长度和线程数计算每条线程下载的数据长度和下载位置。如:文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如上图所示。

3>使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止,代码如下:

HttpURLConnection.setRequestProperty("Range", "bytes=2097152-4194303");

4>保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。

RandomAccessFile threadfile = new RandomAccessFile("QQWubiSetup.exe ","rwd");

threadfile.seek(2097152);//从文件的什么位置开始写入数据

文件实现:

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

public class MulThreadDownloadTest {

public static void main(String[] args) throws Exception{

new MulThreadDownloadTest().downlaod();

}

public void downlaod() throws Exception{

String path = "http://net.itcast.cn/QQWubiSetup.exe";

//文件的长度

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(5*1000);

int length = conn.getContentLength();//得到文件的长度

int threadnum = 5;

int block = length%threadnum==0 ? length/threadnum : length/threadnum+1;//计算每条线程下载的数据长度

File file = new File("QQWubiSetup.exe");

RandomAccessFile rfile = new RandomAccessFile(file, "rwd");

rfile.setLength(length);//把本地文件的长度设置为网络文件的长度

rfile.close();

for(int i=0 ; i < threadnum ; i++){

new DownloadThread(block, url, file ,i).start();

}

}

private final class DownloadThread extends Thread{

private int block;//每条线程下载的数据长度

private URL url;//下载路径

private File file;//本地文件

private int threaid;//线程id

public DownloadThread(int block, URL url, File file, int i) {

this.block = block;

this.url = url;

this.file = file;

this.threaid = i;

}

@Override

public void run() {

try {

int startpos = threaid * block;//计算该线程从文件的什么位置开始下载

int endpos = (threaid+1) * block - 1;//计算该线程下载到文件的什么位置结束

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.setRequestMethod("GET");

conn.setConnectTimeout(5*1000);

conn.setRequestProperty("Range", "bytes="+ startpos+"-"+ endpos);

InputStream inputStream = conn.getInputStream();

RandomAccessFile rfile = new RandomAccessFile(file, "rwd");

rfile.seek(startpos);

byte[] buffer = new byte[1024];

int len = 0;

while( (len = inputStream.read(buffer)) != -1){

rfile.write(buffer, 0, len);

}

rfile.close();

inputStream.close();

System.out.println("线程"+ (threaid+1)+ "下载完成");

} catch (Exception e) {

e.printStackTrace();

}

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: