实现多线程下载同一个文件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wo_aisilebiancheng/article/details/50925907
原理:
 
 
示例代码:
 
 
public class LoadFile {

	private static int threadCount = 3;// 下载的线程数量

	public static void main(String[] args) {
		
		// 1、与服务器建立连接,获得文件的大小,在本地创建一个与需下载文件同等大小的临时文件
		String path = "http://localhost/safe.exe";
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setReadTimeout(5000);
			
			int code = conn.getResponseCode();
			if(200 == code) {
				// 获得文件的长度
				int length = conn.getContentLength();
				System.out.println("文件总长度为:"+length);
				// 在本地创建一个可以随机读取的与源文件同等大小的临时文件
				RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd");
				// 指定文件的长度
				raf.setLength(length);// 设置文件长度
				raf.close();
				
				// 2、实现多线程下载资源
				int blockSize = length / threadCount ;// 每个线程平均需要下载文件的大小
				for(int threadId = 1; threadId <= threadCount; threadId++) {
					// 每个线程下载文件的初始位置和结束位置
					int startIndex = (threadId-1) * blockSize;
					int endIndex = threadId * blockSize - 1;
					// 下载的最后一块的情况
					if(threadCount == threadId) {
						endIndex = length - 1;// 如果不减1的话,就超出了文件的范围
					}
					System.out.println("线程 "+threadId+"下载位置为:"+startIndex+"--->"+endIndex);
					// 启动下载线程
					new DownloadThread(path, startIndex, endIndex, threadId).start();
				}
				
			} else {
				System.out.println("服务器出现错误");
			}
			
		} catch (Exception e) {
			System.out.println("连接服务器URL出现错误");
			e.printStackTrace();
		}
		
	}

}

public class DownloadThread extends Thread {

	private String path;// 服务器路径
	private int startIndex;// 块文件开始位置
	private int endIndex;// 快文件结束位置
	private int threadId;// 线程编号

	public DownloadThread() {

	}

	public DownloadThread(String path, int startIndex, int endIndex, int threadId) {
		this.path = path;
		this.startIndex = startIndex;
		this.endIndex = endIndex;
		this.threadId = threadId;
	}

	@Override
	public void run() {
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setReadTimeout(5000);
			// 提交请求可以从指定位置读取文件
			conn.setRequestProperty("Range", "bytes=" + startIndex + "-"
					+ endIndex);
			int code = conn.getResponseCode();
			// 请求全部文件成功返回200, 请求部分文件成功返回206
			if (206 == code) {
				RandomAccessFile raf = new RandomAccessFile("safe.exe", "rwd");
				// 随机文件从哪里读
				raf.seek(startIndex);// 定位文件

				InputStream is = conn.getInputStream();
				int len = 0;
				byte[] buffer = new byte[1024];
				while ((len = is.read(buffer)) != -1) {
					raf.write(buffer, 0, len);
				}
				
				is.close();
				raf.close();
				System.out.println("线程" + threadId + "下载完毕!!!!");
			} else {
				System.out.println("线程"+threadId+"请求的部分资源失败");
			}

		} catch (Exception e) {
			System.out.println("下载线程的URL连接异常");
			e.printStackTrace();
		}
	}

}
// 别下载太大的文件,可能等待时间很长
/*Output:
文件总长度为:11556608
线程 1下载位置为:0--->3852201
线程 2下载位置为:3852202--->7704403
线程 3下载位置为:7704404--->11556607
线程2下载完毕!!!!
线程1下载完毕!!!!
线程3下载完毕!!!!
*/



 

猜你喜欢

转载自blog.csdn.net/wo_aisilebiancheng/article/details/50925907