• 多线程下载辅助类实现


    如需转载,必须注明转自: 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);
    	}
    }
    


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







  • 相关阅读:
    NOIp2016 D2T3 愤怒的小鸟【搜索】(网上题解正解是状压)
    NOIp2018D1T1 积木大赛 【思维】
    NOIp2018D1T2 货币系统【分析&完全背包】
    NOIp2017D1T2 时间复杂度【模拟】
    NOIp2015D1T3 斗地主【暴搜】
    NOIp2013D2T3 华容道【搜索&图论-最短路】
    Andrew算法求二维凸包-学习笔记
    最小割的一些小技巧(实用小干货)
    USACO4.3 Buy Low, Buy Lower【简单dp·高精度】
    iOS本地推送与远程推送详解
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3058317.html
Copyright © 2020-2023  润新知