• Java多线程下载文件


    public class DownLoad {
    	private int threadSize = 3;
    
    	public void URLLoad(String source, String fileName) {
    		RandomAccessFile access = null;
    		try {
    			// 打开连接,获取内容长度,计算每个线程下载长度
    			URL url = new URL(source);
    			int sourceSize = url.openConnection().getContentLength();
    			int threadLoadSize = sourceSize / threadSize;
    			// 初始化接受文件
    			File file = new File(fileName);
    			if (!file.exists()) {
    				file.createNewFile();
    			}
    			access = new RandomAccessFile(file, "rw");
    			for (int i = 0; i < sourceSize; i++) {
    				access.write(0);
    			}
    			// 开启线程下载
    			for (int i = 0; i < threadSize; i++) {
    
    				if (i != threadSize - 1) {
    					new FileLoadThread(threadLoadSize * i, threadLoadSize
    							* (i + 1), url.openStream(), new RandomAccessFile(
    							file, "rw")).start();
    				} else {
    					// 最后一个线程下载
    					int rem = sourceSize % threadSize;
    					new FileLoadThread(threadLoadSize * i, threadLoadSize
    							* (i + 1) + rem, url.openStream(), access).start();
    				}
    			}
    
    		} catch (MalformedURLException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	//下载线程
    	class FileLoadThread extends Thread {
    		private int bufferSize = 32;
    		private int start;
    		private int end;
    		private InputStream input;
    		private RandomAccessFile access;
    
    		public FileLoadThread(int start, int end, InputStream input,
    				RandomAccessFile access) {
    			this.start = start;
    			this.end = end;
    			this.input = input;
    			this.access = access;
    		}
    
    		@Override
    		public void run() {
    			System.out.println(Thread.currentThread().getName() + "进入下载");
    			System.out.println("start:" + start + ";end:" + end);
    			try {
    				// 初始化下载,存储进度
    				input.skip(start);
    				access.seek(start);
    				// 要读取总长度
    				int readSize = end - start;
    				// 已读取总长度
    				int useReadSize = 0;
    				// 缓冲数组
    				byte[] buffer = new byte[bufferSize];
    				int count = 0;
    				// 开始下载
    				while ((count = input.read(buffer)) != -1) {
    					useReadSize += count;
    					// 如果已读取总长度大于要读取长度,则在缓冲数组中截取需要读取的数据
    					if (useReadSize > readSize) {
    						int size = count - (useReadSize - readSize);
    						access.write(buffer, 0, size);
    						break;
    					} else {
    						access.write(buffer);
    					}
    				}
    			} catch (FileNotFoundException e) {
    				e.printStackTrace();
    			} catch (IOException e) {
    				e.printStackTrace();
    			} finally {
    				try {
    					if (input != null) {
    						input.close();
    					}
    					if (access != null) {
    						access.close();
    					}
    				} catch (IOException e) {
    					e.printStackTrace();
    				}
    			}
    			System.out.println(Thread.currentThread().getName() + "下载完成");
    		}
    	}
    
    	public static void main(String[] args) {
    		DownLoad load = new DownLoad();
    		load.URLLoad("http://www.baidu.com/", "D:/juhua.html");
    	}
    }

  • 相关阅读:
    【状压】孤岛营救问题
    【网络流】魔术球问题
    【状压】软件补丁问题
    [网络流]最大流
    [网络流]小M的作物
    简单版AC自动机
    KMP
    sql 检索字符串
    Mysql触发器 :当一个表发生插入或更新时,将数据同步到另一张表中
    sql server触发器 :当一个表发生插入或更新时,将数据同步到另一张表中
  • 原文地址:https://www.cnblogs.com/yht520/p/3589653.html
Copyright © 2020-2023  润新知