Java实现多线程断点下载

多线程下载的原理图


实现的代码

public class MuThreadDownloader {
	/**下载线程数量*/
	public static int threadCount = 3;
	public static int runningThread = 3;
	public static void main(String[] args) throws IOException {
		String spec = "http://localhost:8083/aliww.exe";
		URL url = new URL(spec);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(4000);
		conn.setRequestMethod("GET");
		int code = conn.getResponseCode();
		if(code == 200){
			int length = conn.getContentLength();
			System.out.println("fileSize:" + length);
			/**随机操作文件类*/
			RandomAccessFile raf = new RandomAccessFile("阿里旺旺.exe", "rwd");
			/**在本地创建一个同样大小的临时文件*/
			raf.setLength(length);
			raf.close();
			/**每个线程下载的大小*/
			int blockSize = length / threadCount;
			for (int threadId = 1; threadId <= threadCount; threadId++) {
				//每个线程下载的起始位置
				int startIndex = (threadId - 1) * blockSize;
				//每个线程下载的结束位置
				int endIndex = threadId*blockSize - 1;
				if(threadId == threadCount){
					endIndex = length;
				}
				new DownLoaderThread(startIndex, endIndex, spec,threadId).start();
				System.out.println("startIndex-endIndex  " + startIndex + "-" + endIndex);
			}
		}
	}
	public static class DownLoaderThread extends Thread{
		private int startIndex;
		private int endIndex;
		private String path;
		private int threadId;
		public DownLoaderThread(int startIndex, int endIndex, String path,int threadId) {
			this.startIndex = startIndex;
			this.endIndex = endIndex;
			this.path = path;
			this.threadId = threadId;
		}
		
		@Override
		public void run() {
			try {
				File file = new File(threadId + ".txt");
				//每个线程下载之前先判断是否存在记录进度的文件
				if(file.exists() && file.length() > 0){
					InputStream is = new FileInputStream(file);
					byte [] buffer = new byte[1024];
					is.read(buffer);
					System.out.println(new String(buffer));
					startIndex = Integer.parseInt(new String(buffer).trim());
				}
				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				//请求服务器下载部分的资源,指定资源的起始位置
				conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);	
				conn.setConnectTimeout(5000);
				//从服务器返回全部的资源返回200 部分资源返回206
				int code = conn.getResponseCode();
				System.out.println("code:" + code);
				if(code == 206){
					
					System.out.println("线程-" + threadId + "从" + startIndex + "位置开始下载");
					InputStream is = conn.getInputStream();
					RandomAccessFile raf = new RandomAccessFile("阿里旺旺.exe", "rwd");
					//设置写入文件的起始位置
					raf.seek(startIndex);
					byte[] buff = new byte[1024];
					int len = 0;
					//用于记录当前下载的进度
					int total = startIndex;
					while((len = is.read(buff))!=-1){
						raf.write(buff, 0, len);
						total += len;
						System.out.println("线程-" + threadId + "下载到" + total + "字节");
						RandomAccessFile accessFile = new RandomAccessFile(file, "rwd");
						accessFile.write(String.valueOf(total).getBytes());
						accessFile.close();
//						FileOutputStream fos = new FileOutputStream(file);
//						fos.write(String.valueOf(total).getBytes());
//						fos.flush();
//						fos.close();
					}
					is.close();
					raf.close();
					runningThread -- ;
					System.out.println("线程-" + threadId + "下载完成......");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(runningThread == 0){
					for (int i = 1; i <= threadCount; i++) {
						File file = new File(i + ".txt");
						file.deleteOnExit();
					}
				}
			}
		}
	}
}

要点:

1、告诉服务器要请求部分资源

//请求服务器下载部分的资源,指定资源的起始位置

	     conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值