多线程下载

多线程下载:

多线程下载的实现过程:

1>首先得到下载文件的长度,然后设置本地文件的长度。
   HttpURLConnection.getContentLength();
   RandomAccessFile file = new RandomAccessFile("xx.exe","rwd");
   file.setLength(filesize);//设置本地文件的长度

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

3>使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,如:    HttpURLConnection.setRequestProperty("Range", "bytes=startpositian-endposition");

4>保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
   RandomAccessFile threadfile = new RandomAccessFile("xx.exe ","rwd");
   threadfile.seek(startposition);//从文件的什么位置开始写入数据
 
多线程下载实现代码:

public class MulThreadDownload {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String path = "http://www.xx.com/xx.exe";
		try {
			new MulThreadDownload().download(path, 3);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 从路径中获取文件名称
	 * @param path 下载路径
	 * @return
	 */
	public static String getFilename(String path){
		return path.substring(path.lastIndexOf('/')+1);
	}
	/**
	 * 下载文件
	 * @param path 下载路径
	 * @param threadsize 线程数
	 */
	public void download(String path, int threadsize) throws Exception{
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		conn.setRequestMethod("GET");
		conn.setConnectTimeout(5 * 1000);
		int filelength = conn.getContentLength();//获取要下载的文件的长度
		String filename = getFilename(path);//从路径中获取文件名称
		File saveFile = new File(filename);
		RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");
		accessFile.setLength(filelength);//设置本地文件的长度和下载文件相同
		accessFile.close();
		//计算每条线程下载的数据长度
		int block = filelength%threadsize==0? filelength/threadsize : filelength/threadsize+1;
		for(int threadid=0 ; threadid < threadsize ; threadid++){
			new DownloadThread(url, saveFile, block, threadid).start();
		}
	}
	
	private final class DownloadThread extends Thread{
		private URL url;
		private File saveFile;
		private int block;//每条线程下载的数据长度
		private int threadid;//线程id

		public DownloadThread(URL url, File saveFile, int block, int threadid) {
			this.url = url;
			this.saveFile = saveFile;
			this.block = block;
			this.threadid = threadid;
		}

		@Override
		public void run() {
			//计算开始位置公式:线程id*每条线程下载的数据长度= ?
		       //计算结束位置公式:(线程id +1)*每条线程下载的数据长度-1 =?
			int startposition = threadid * block;
			int endposition = (threadid + 1 ) * block - 1;
			try {
				RandomAccessFile accessFile = new RandomAccessFile(saveFile, "rwd");
				accessFile.seek(startposition);//设置从什么位置开始写入数据
				HttpURLConnection conn = (HttpURLConnection)url.openConnection();
				conn.setRequestMethod("GET");
				conn.setConnectTimeout(5 * 1000);
				conn.setRequestProperty("Range", "bytes="+ startposition+ "-"+ endposition);
				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();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}		
	}

}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值