新浪微博 Github

多线程下载辅助类实现

如需转载,必须注明转自: http://blog.csdn.net/xiazdong/article/details/7738298


使用声明:

类名:MultiThreadDownloadUtil

API:

(1)download(String path,int count);

path:文件URL;

count:线程数量;

 

package org.xiazdong.multidownload.util;

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


public class MultiThreadDownloadUtil{
	private static int filesize;
	private static int block;
	private static String filename;
	private static int downloadsize;
	private class MyThread extends Thread{
		private int i;			//线程ID
		private String path;	//下载文件的URL

		public MyThread(int i, String path) {
			this.i = i;
			this.path = path;
			downloadsize = 0;
		}
		@Override
		public void run() {
			try{
				System.out.println("线程"+(i+1)+"开始下载");
				//1.打开文件,并定位位置
				RandomAccessFile raf = new RandomAccessFile(new File(filename), "rwd");
				raf.seek(i*block);			//定位到此线程要负责下载的位置
				int start = i*block;
				int end = (i+1)*block-1;
				//2.连接服务器
				URL url = new URL(path);
				HttpURLConnection conn = (HttpURLConnection)url.openConnection();
				conn.setRequestMethod("GET");
				conn.setRequestProperty("range", "bytes="+start+"-"+end);	//发出请求头
				
				if(conn.getResponseCode()==206){		//注意:分段下载的返回码为206,而不是200
					InputStream in = conn.getInputStream();
					int length = 0;
					byte[]data = new byte[1024];
					while((length=in.read(data))!=-1){
						raf.write(data,0,length);		//写入本地文件
					}
				}
				//显示下载进度
				downloadsize += (end-start);
				System.out.println("已下载"+downloadsize/1024.0+"k,共"+filesize/1024.0+"k");
				//3.关闭文件
				raf.close();
				System.out.println("线程"+(i+1)+"结束下载...");
			}
			catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	/**
	 * 下载文件
	 * @param path			URL
	 * @param threadcount   线程数
	 * @throws Exception
	 */
	public static void download(String path,int threadcount) throws Exception{
		filename = path.substring(path.lastIndexOf('/')+1);
		filesize = getFileSize(path);
		block = getBlockSize(filesize,threadcount);
		createLocalRandomFile(filesize);
		MultiThreadDownloadUtil mdu = new MultiThreadDownloadUtil();
		for(int i=0;i<threadcount;i++){
			mdu.new MyThread(i,path).start();
		}
	}
	/**
	 * 创建一个本地文件,并设置文件的大小
	 * @param filesize
	 * @throws Exception
	 */
	private static void createLocalRandomFile(int filesize) throws Exception {
		RandomAccessFile raf = new RandomAccessFile(new File(filename), "rwd");
		raf.setLength(filesize);
		raf.close();
	}
	/**
	 * 根据文件总大小和线程数求出每个线程要下载的数据量
	 * @param filesize
	 * @param threadcount
	 * @return
	 */
	private static int getBlockSize(int filesize, int threadcount) {
		return filesize%threadcount==0?filesize/threadcount:(filesize/threadcount+1);
	}
	/**
	 * 求出文件总大小
	 * @param path
	 * @return
	 * @throws Exception
	 */
	private static int getFileSize(String path) throws Exception{
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		conn.setRequestMethod("GET");
		if(conn.getResponseCode()==200){
			return conn.getContentLength();
		}
		else{
			return 0;
		}
	}
}

 

 

测试类:


package org.xiazdong.download;

import org.xiazdong.multidownload.util.MultiThreadDownloadUtil;


public class MultiThreadDownloader {

	public static void main(String[] args) throws Exception {
		int threadCount = 3;	//指定线程数量
		String path = "http://dlc2.pconline.com.cn/filedown_61761_6694063/drivethelife2010_pconline_setup.exe";	//指定下载文件路径
		MultiThreadDownloadUtil.download(path, threadCount);
	}
}


将此文件下载到工程目录后,运行可用;







posted @ 2012-07-11 22:49  xiazdong  阅读(166)  评论(0编辑  收藏  举报