多线程下载辅助类实现
如需转载,必须注明转自: 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); } }
将此文件下载到工程目录后,运行可用;