Java实现多线程下的下载断点续传

基本思想是停止时以Map的形式存入文件时,等到再次下载时从文件中读取继续下载
1.首先写一个文件工具类,用来实现文件和Map集合的相互转换

import java.io.File;
import java.util.Map;
import java.io.*;

public class FileUtil {
	public  static void mapToFile(String filePath,Map map) throws Exception{
		File file = fileIsExist(filePath);
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
		oos.writeObject(map);
		oos.flush();
		oos.close();
	}
	@SuppressWarnings("unchecked")
	public static Map fileToMap(String filePath){
		Map map = null;
		try {
			File file = fileIsExist(filePath);
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
			map = (Map) ois.readObject();
			ois.close();
		} catch (Exception e) {
			//e.printStackTrace();
		}
		return map;
	}
	private static File fileIsExist(String filePath) {
		File file = new File(filePath);
		if (!file.exists()) {
			System.out.println("文件不存在,现在创建");
			try {
				file.createNewFile();
			} catch (IOException e) {
				System.out.println("路径:" + filePath + "创建失败");
				e.printStackTrace();
			}
		}
		return file;
	}

}

2.url.properties参数配置

url:http://mirror.bit.edu.cn/apache/tomcat/tomcat-9/v9.0.22/bin/apache-tomcat-9.0.22.zip

threadNumber:3
path:D:/
mapPath:D:/map.txt

3.多线程下实现文件的断点续传

public class DownLoad {
	private static int downLoadCount=0;
	private static int downSize = 0;
	private static double percent;//当前文件长度的百分之一是多少
	private static int now=0;
	private static String s;
	private static String path;
	private static int threadNumber;
	private static int test=0;
	private static String mapPath;
	static Map map=new HashMap<>();
	/**
	 * 一下代码是从url.properties读取各参数
	 */
	static {
		s=MyProperties.getInstance().getProperty("url");
		path=MyProperties.getInstance().getProperty("path");
		threadNumber=Integer.parseInt(MyProperties.getInstance().getProperty("threadNumber"));
		mapPath=MyProperties.getInstance().getProperty("mapPath");
	}
	private static Semaphore semaphore = new Semaphore(threadNumber,true);//此变量用来控制最多线程的个数
	public static void main(String[] args) throws IOException, InterruptedException {
		URL url=new URL(s);
		URLConnection conn=url.openConnection();
		long time=System.currentTimeMillis();
		int length=conn.getContentLength();//计算文件的长度
		percent=length/100;
		int blockSize=1024*1024*1;//每一块的大小
		int forCount;
		 forCount=length%blockSize==0? length/blockSize  :(length/blockSize+1);//计算需要下载的线程个数
		for(int i=0;i map1=FileUtil.fileToMap(mapPath);
		System.out.println(map);
		int pointer=0;
		if(map1!=null && map1.get("part"+i)!=null){
			pointer=map1.get("part"+i)-begin;
			now+=pointer;
			begin+=map1.get("part"+i);
		}
		int count;
		int total=0;
		byte buffer[]=new byte[1024];
		in.skip(begin);
		savePath.seek(pointer);
		int downSize=begin;
		System.out.println("第"+i+"块开始下载");
		while( (count=in.read(buffer))!=-1 && downSizeend){
				count=1024-(downSize+count-end);
			}
			downSize+=count;
			total+=count;
			/*System.out.println(percent);
			System.out.println(total);*/
			if(total/percent>1){
				synchronized (DownLoad.class) {
					for(int j=0;j100)
							break;
						System.out.println("当前进度"+now+"%");
					}
					
					total=0;
				}
			
			}
			savePath.write(buffer, 0, count);
			
			map.put("part"+i, downSize);
			//将map的内容存入txt文件
			FileUtil.mapToFile(mapPath, map);
		}
		System.out.println("第"+i+"块下载结束");
		synchronized (DownLoad.class) {
			DownLoad.downLoadCount++;
			DownLoad.class.notifyAll();
		}
		System.out.println(test);
		//结束时调用Release方法
		semaphore.release();
		test--;
		in.close();
		savePath.close();
	}
}

你可能感兴趣的:(JAVA)