【JAVA应用】多线程断点下载

问题:多线程下载的好处?

多线程下载比单线程下载快,主要的原因是采用多线程下载,可以抢占更多的服务器资源。抢占Cpu的处理空间,实现更快的下载速度


问题:多线程下载位置的确定?

开启N条线程下载文件,假设文件大小为buf,那么每条线程的下载量为:
buf%N==0?buf/N:buf/N+1;

那么,每一条线程应该从网络文件的什么位置开始下载??

假设线程id号threadid为0,1,2,每一条线程下载的数据量为block=4

第一个文件从threadid*block开始下载,结束位置(threadid+1)*block-1

所以公式为:
int start=threadid*block;
int end=(threadid+1)*block-1;



多线程下载源码(仅供参考)

package cn.deu.hpu.download;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MulThreadDownLoad {
	
	public static void main(String[] args) throws Exception{
		String path="http://192.168.111.104:8080/web/gg.jpg";
		new MulThreadDownLoad().download(path,3);
	}
	
	/*下载文件
	 * path 网络文件路径
	 * */
	public void download(String path,int threadsize)throws Exception{
		URL url=new URL(path);
		HttpURLConnection conn=(HttpURLConnection) url.openConnection();
		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");
			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 String getFilename(String path) {
		//从URL地址的最后一个"/"后开始记录文件名
		return path.substring(path.lastIndexOf("/")+1);
	}
	
	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);
				//请求某一段数据的话,请求码不是200,是206
				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)+"线程已经下载完成");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}

转载请注明出处!程序猿之洞:http://blog.csdn.net/acmman

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光仔December

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值