java多线程下载http协议文件

package com.wild.http;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

public class ThunderDownLoad {
	private long contentLength;
	private long downAllLength;

	public static void main(String[] args) {
		new ThunderDownLoad().HttpDown("http://hbimg.b0.upaiyun.com/7f25d18a6e5f7e81d84333bded49b266f8599b511ae70-hVkEGh_fw658", "D:/",
				5);
	}

	public void HttpDown(String urlPath, String dirPath, int threadCount) {
		try {
			URL url = new URL(urlPath);
			contentLength = getDownFileSize(url);
			long threadSize = contentLength % threadCount == 0 ? contentLength / threadCount
					: (contentLength / threadCount + 1);
			String filePath = getDownFilePath(urlPath, dirPath);
			if (contentLength != 0) {
				startDownLoad(url, threadCount, threadSize, filePath);
			} else {
				System.out.println("文件下载失败...");
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

	// 给对象get方法
	public long getContentLength() {
		return contentLength;
	}

	public long getDownAllLength() {
		return downAllLength;
	}

	/**
	 * 
	 * @param url:下载的地址
	 * @param threadCount:下载启动的线程数
	 * @param threadSize2:下载文件的大小
	 * @param filePath:下载的文件的路径
	 */
	private void startDownLoad(URL url, int threadCount, long threadSize, String filePath) {
		for (int i = 1; i <= threadCount; i++) {
			long beginLoc = (i - 1) * threadSize + (i == 1 ? 0 : 1);
			long endLoc = i * threadSize;
			new Thread(new downFileTask(i, beginLoc, endLoc, filePath, url)).start();

		}
	}

	private long getDownFileSize(URL url) {
		try {
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod("HEAD");
			con.connect();// 再次连接
			return con.getContentLength();
		} catch (ProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return 0;
	}

	// 获取文件下载地址
	private String getDownFilePath(String urlPath, String dirPath) {
		String filename = urlPath.substring(urlPath.lastIndexOf("/"));
		File file = new File(dirPath + filename);
		if (file.exists()) {
			filename = filename.replace(".", "-" + System.currentTimeMillis() + ".");
		}
		return dirPath + filename;
	}

	/**
	 * 
	 * @param url:下载文件的位置
	 * @return:下载文件的大小
	 */
	public long downDownSize(URL url) {
		try {
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod("HEAD");
			con.connect();// 再次连接
			return con.getContentLength();// 赋值
		} catch (ProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return 0;
	}

	// 开始线程下载任务
	public class downFileTask implements Runnable, Serializable {
		private static final long serialVersionUID = -6119263155005060026L;

		private int threadId;// 线程编号
		private long beginLocation;// 开始的字节数的位置
		private long endLocation;// 结束的字节位置
		@SuppressWarnings("unused")
		private long downloadContentLength;// 当前线程下载的长度
		private String downFilePath;// 文件下载保存路径
		private URL url;

		public downFileTask(int threadId, long beginLocation, long endLocation, String downFilePath, URL url) {
			this.threadId = threadId;
			this.beginLocation = beginLocation;
			this.endLocation = endLocation;
			this.downFilePath = downFilePath;
			this.url = url;
		}

		public void run() {
			System.out.println("启动了" + threadId + "个线程");
			try {
				RandomAccessFile raf = new RandomAccessFile(downFilePath, "rwd");
				raf.seek(beginLocation);
				HttpURLConnection con = (HttpURLConnection) url.openConnection();
				con.setRequestMethod("GET");
				con.setRequestProperty("Range", "bytes=" + beginLocation + "-" + endLocation);

				// 获取下载数据流
				InputStream in = con.getInputStream();
				byte[] by = new byte[1024 * 1024];
				int len = 0;

				while ((len = in.read(by)) != -1 && MyThunder.flag) {
					downloadContentLength += len;
					downAllLength += len;
					raf.write(by, 0, len);
				}
				raf.close();
				System.out.println("MyThunder.flag:" + MyThunder.flag);
				System.out.println("第" + threadId + "个线程下载完成..,下载从" + beginLocation + "到" + endLocation);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		};
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值