java版多线程下载

<pre name="code" class="java"><span style="font-size:24px;"><span style="font-size:24px;">package com.melody.clf;

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

/**
 *  开始位置:id*size
 *  结束位置:(id + 1)* size -1
 *  最后一个线程的结束位置:length -1
 * @author Administrator
 *
 */
public class Main {
	static String path = "http://192.168.119.14/ep.exe";
	static int threadCount = 3;     //定义线程数量
	
	public static void main(String[] args) {
		//发送http请求,拿到目标文件长度
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setReadTimeout(8000);
			conn.setConnectTimeout(8000);
			
			if(conn.getResponseCode() == 200){
				//获取长度
				int length = conn.getContentLength();
				
				//创建临时文件   先占用硬盘空间  
				// File(路径,文件名)    路径不写默认存到项目的根目录
 				File file = new File(getNameFrompath(path));
 				
 				//随机存储,创建临时文件  
 				/**
 				 * mode :
 				 *  r:只读
 				 *  rw:读写,文件不存在,则创建
 				 *  rws:读写,对文件内容或者元数据的每个更新都同步写入到底层存储设备
 				 *  rwd:读写,对文件内容的每个更新都同步写入到底层存储设备
 				 */
				RandomAccessFile raf = new RandomAccessFile(file, "rwd");
				//设置临时文件大小与目标文件一直
				raf.setLength(length);
				raf.close();
				
				//计算每个线程区间
				int size = length / threadCount;
				//计算每个线程开始的位置和结束的位置
				for(int id = 0; id < threadCount; id++){
					int startIndex = id * size;   //开始位置
					int endIndex = (id+1)*size-1;    //结束位置
					if(id == threadCount -1){			//最后一个线程结束的位置
						endIndex = length -1;
					}
					System.out.println("线程" + id +"下载的区间" + startIndex + "~" + endIndex);
				
					new DownLoad(id, startIndex, endIndex).start();
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// 截取字段获取文件名
	public static String getNameFrompath(String path){
		//搜索最后一个斜杠
		int index = path.lastIndexOf("/");
		// 斜杠前后开始截取
		return path.substring(index + 1);
	}
	
	public static class DownLoad extends Thread{
		
		int threadId;		     //线程ID
		int startIndex;		//开始区间
		int endIndex;		//结束区间
		
		public DownLoad(int threadId, int startIndex, int endIndex) {
			super();
			this.threadId = threadId;
			this.startIndex = startIndex;
			this.endIndex = endIndex;
		}
		
		public void run() {
			//发送http请求,请求要下载的数据
			try {
				URL url = new URL(Main.path);
				HttpURLConnection conn =(HttpURLConnection) url.openConnection();
				conn.setRequestMethod("GET");
				conn.setReadTimeout(8000);
				conn.setReadTimeout(8000);
				
				//设置请求数据区间    从startIndex到endIndex之间
				conn.setRequestProperty("Range", "bytes=" + startIndex +"-" + endIndex);
				//请求部分数据成功的响应吗是206
				if(conn.getResponseCode() == 206){
					InputStream is = conn.getInputStream();
					//开始读取数据
					byte[] b = new byte[1024];
					int len = 0;
					//当前线程下载的总进度
					int total = 0;    
					//读取临时文件里的数据
					File file = new File(getNameFrompath(path));
					RandomAccessFile raf = new RandomAccessFile(file, "rwd");
					//设置写入文件的开始位置
					raf.seek(startIndex);
					//没读取1K就把这1K写到输出流里面
					while((len = is.read(b)) != -1){
						raf.write(b,0,len);
						total +=len;
						System.out.println("线程" + threadId +"下载了:"+total);
					}
					raf.close();
					System.out.println("线程" + threadId +"下载完毕"+"-------------------------");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	
	
	
	
}
</span>
</span>


 

你可能感兴趣的:(java版多线程下载)