Java多线程断点下载

使用多线程下载文件可以更快完成文件的下载,多线程下载文件之所以快,是因为其抢占的服务器资源多。如:假

 

设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机中并非并发执行,而

 

是由CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,假设

 

一秒内CPU分配给每条线程的平均执行时间是10ms,A应用在服务器中一秒内就得到了990ms的执行时间,而其

 

他应用在一秒内只有10ms的执行时间。就如同一个水龙头,每秒出水量相等的情况下,放990毫秒的水肯定比放

 

10毫秒的水要多。

 

 

 

代码实现:

 

package cn.mzba.download;

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

public class MulThreadDownloader {

	/**
	 * 1、首先获取网络上的内容,然后获取文件的长度,标题。
	 * 	然后在本地上生成一个同样大小并且同名的文件。
	 * 2、执行线程
	 * 3、线程首先定义一个随机输入流,用来下载文件同步写入本地文件
	 * 	  设置Range从指定的开始位置-结束位置下载文件。
	 * 4、获取服务器返回的输入流写入文件。
	 *   
	 */
	public static void main(String[] args)throws Exception {
		String path = "http://www.world3dmodel.com/bbs/attachments/month_1012/10121516044465687722ce156c.jpg";
		new MulThreadDownloader().download(path,3); 
		System.in.read();
	}

	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 length = conn.getContentLength(); //获取文件长度
		File localfile = new File(getFileName(path));
		RandomAccessFile file = new RandomAccessFile(localfile, "rwd");
		file.setLength(length);
		file.close();
		//计算每条线程下载的数据长度
		int block = length % threadsize == 0 ? length / threadsize : length / threadsize + 1;
		for(int i = 0;i < threadsize; i++){
			new DownLoadThread(i,url,block,localfile).start();
		}
	}
	private final class DownLoadThread extends Thread{

		private int threadid;
		private URL url;
		private int block;
		private File localfile;
		public DownLoadThread(int threadid, URL url, int block, File localfile) {
			this.threadid = threadid;
			this.block = block;
			this.url = url;
			this.localfile = localfile;
		}
		
		@Override
		public void run() {
			int startposition = threadid * block;  //从网络文件的什么位置开始下载数据
			int endposition = startposition + block -1; //下载到文件的什么位置结束
			RandomAccessFile file;
			try {
				file = new RandomAccessFile(localfile, "rwd");
				file.seek(startposition);
				HttpURLConnection conn = (HttpURLConnection)url.openConnection();
				conn.setRequestMethod("GET");
				conn.setConnectTimeout(5 * 1000);
				conn.setRequestProperty("Range", "bytes=" + startposition + "-" + endposition);
				InputStream is = conn.getInputStream();
				byte[] buffer = new byte[1024];
				int len = 0;
				while((len = is.read(buffer)) != -1){
					file.write(buffer,0,len);
				}
				is.close();
				file.close();
				System.out.println("线程id" + threadid + "已经下载完成");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			super.run();
		}
		
	}
	
	public static String getFileName(String path){
		return path.substring(path.lastIndexOf("/") + 1);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值