Java实现多线程下载

public class Download {
	// 服务器的下载地址
//	public static String FILEPATH = "http://192.168.86.1:8080/1-9.zip";
	public static String FILEPATH = "http://dldir1.qq.com/invc/tt/QQBrowserSetup.exe";
	// 本地保存的路径
	public static String DESTINATION = "D:\\";
	// 下载的线程数
	public static int THREADCOUNT = 5;

	public static void main(String[] args) throws Exception {

		URL url = new URL(FILEPATH);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// 连接超时
		conn.setConnectTimeout(5 * 1000);
		// 下载通过GET请求
		conn.setRequestMethod("GET");
		// 设置代理
		conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36");
		conn.setRequestProperty("Connection", "keep-alive");
		if (conn.getResponseCode() == 200) {
			// 文件的大小
			int contentLength = conn.getContentLength();
			// 将文件分成5份
			int blocksize = contentLength / THREADCOUNT;
			// 此类的实例支持对随机访问文件的读取和写入
			// 并建立一个空的文件
			RandomAccessFile randomAccessFile = new RandomAccessFile(new File(Download.DESTINATION + Download.getFileName(Download.FILEPATH)), "rwd");
			randomAccessFile.setLength(contentLength);
			randomAccessFile.close();
			conn.disconnect();
			for (int i = 0; i < THREADCOUNT; i++) {
				// 少下载一个字节
				int startpos = i * blocksize;
				int endpos = (i + 1) * blocksize - 1;
				if (i == THREADCOUNT - 1) {
					endpos = contentLength;
				}
				new Thread(new DownloadTask(i, startpos, endpos)).start();
			}
		} else {

			System.out.println("服务器出错!");
		}

	}

	// 截取文件名
	public static String getFileName(String path) {

		return path.substring(path.lastIndexOf("/") + 1, path.length());
	}
}

// 多线程的任务
class DownloadTask implements Runnable {

	public DownloadTask(int id, int startpos, int endpos) {
		this.id = id;
		this.startpos = startpos;
		this.endpos = endpos;
	}

	int id;
	int startpos;
	int endpos;

	@Override
	public void run() {
		try {
			URL url = new URL(Download.FILEPATH);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(5 * 1000);
			conn.setRequestMethod("GET");
			// Request only part of an entity. Bytes are numbered from 0.
			// eg:Range: bytes=500-999
			conn.setRequestProperty("Range", "bytes=" + startpos + "-" + endpos + "");
			conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36");
			conn.setRequestProperty("Connection", "keep-alive");

			// HTTP Status-Code 206: Partial Content.
			if (conn.getResponseCode() == 206) {
				InputStream is = conn.getInputStream();
				RandomAccessFile randomAccessFile = new RandomAccessFile(new File(Download.DESTINATION + Download.getFileName(Download.FILEPATH)), "rwd");
				// 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
				randomAccessFile.seek(startpos);
				int len = 0;
				byte[] buffer = new byte[1024];
				while ((len = is.read(buffer)) != -1) {
					randomAccessFile.write(buffer, 0, len);
				}
				is.close();
				randomAccessFile.close();
				conn.disconnect();
				System.out.println("线程" + id + ":下载完毕");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

猜你喜欢

转载自4incloud.iteye.com/blog/1997027
今日推荐