java压缩与解压缩

主要用到apache的ant.jar,也可用jdk的相关类,但会有中文乱码问题。最重要的俩类是ZipFile和ZipEntry,前者将zip文件转为java对象,后者将zip文件中的条目文件转为java对象。 核心代码如下:

压缩代码:

ZipOutputStream zipOs = new ZipOutputStream(fos);
ZipEntry zipEntry = new ZipEntry("entryName");
zipOs.putNextEntry(zipEntry);

解压缩代码:

Enumeration<ZipEntry> entries = zipFile.getEntries();
ZipEntry zipEntry = entries.nextElement();
InputStream ins = zipFile.getInputStream(zipEntry);

需要注意的地方:

针对空文件夹需要特殊处理,需要往Entry中放入"/"+文件夹名+"/"项

zipOs.putNextEntry("/");

详细点的练习: /** * 测试文件压缩与解压缩 * */ public class TestZip {

	public static void main(String[] args) {
		//-->压缩单个文件
		zipSingleFileOrFolder("D:\\BIZFLOW\\src\\tst\\新建文本文档.zip", "D:\\BIZFLOW\\src\\tst\\新建文本文档.txt");
		//-->压缩文件夹
		//zipSingleFileOrFolder("D:\\BIZFLOW\\src\\tst.zip", "D:\\BIZFLOW\\src\\tst");
		//-->压缩多个文件(不指定压缩文件保存路径)
		//zipMultiFiles("","D:\\BIZFLOW\\src\\tst\\新建文本文档.txt","D:\\BIZFLOW\\src\\tst\\新建文本文档 - 副本.txt");
		//-->压缩多个文件(指定压缩文件保存路径)
		//zipMultiFiles("D:\\BIZFLOW\\src\\tst\\新建.zip","D:\\BIZFLOW\\src\\tst\\新建文本文档.txt","D:\\BIZFLOW\\src\\tst\\新建文本文档 - 副本.txt");
		//-->解压缩文件
		//unzipFile("D:\\BIZFLOW\\src\\tst\\新建", "D:\\BIZFLOW\\src\\tst\\新建文本文档.txt等.zip");
	}
	
	/**
	 * 压缩单个文件/文件夹
	 * @param destPath 压缩文件保存路径(为空串/null时默认压缩路径:待压缩文件所在目录,压缩文件名为待压缩文件/文件夹名+“等.zip”)
	 * @param srcPath 待压缩的文件路径
	 */
	public static void zipSingleFileOrFolder(String destPath, String srcPath) {
		if(StringUtils.isBlank(srcPath)) {
			throw new RuntimeException("待压缩文件夹不可为空!");
		}
		if(StringUtils.isNotBlank(destPath) && !destPath.endsWith(".zip")) {
			throw new RuntimeException("保存文件名应以.zip结尾!");
		}
		File file = new File(srcPath);
		if(!file.exists()) {
			throw new RuntimeException("路径'"+srcPath+"'下未找到文件");
		}
		if(file.isDirectory()) {
			//压缩文件夹
			zipFolder(destPath, srcPath);
		} else {
			//压缩单个文件
			zipFile(destPath, srcPath); 
		}
	}
	
	/**
	 * 压缩多个文件
	 * @param destPath 压缩文件保存路径(为空串/null时默认压缩路径:待压缩文件所在目录,压缩文件名为第一个待压缩文件名+“等.zip”)
	 * @param srcPaths 待压缩文件路径集合
	 */
	public static void zipMultiFiles(String destPath, String...srcPaths) {
		if(srcPaths==null || srcPaths.length==0) {
			throw new RuntimeException("待压缩文件夹不可为空!");
		}
		if(StringUtils.isNotBlank(destPath) && !destPath.endsWith(".zip")) {
			throw new RuntimeException("保存文件名应以.zip结尾!");
		}
		zipFiles(destPath, srcPaths);
	}
	
	/**
	 * 解压缩文件
	 * @param destPath 解压缩路径(为空串/null时默认解压缩路径:压缩文件所在目录)
	 * @param zipPath 压缩文件路径
	 */
	public static void unzipFile(String destPath, String zipPath) {
		if(StringUtils.isBlank(zipPath)) {
			throw new RuntimeException("压缩文件路径不可为空!");
		}
		if(!zipPath.endsWith(".zip")) {
			throw new RuntimeException("保存文件名应以.zip结尾!");
		}
		File file = new File(zipPath);
		if(StringUtils.isBlank(destPath)) {
			destPath = getUnzipBasePath(file);
		}
		if(!file.exists()) {
			throw new RuntimeException("路径'"+zipPath+"'下未找到文件");
		}
		ZipFile zipFile;
		int len;
		byte[] buff = new byte[1024];
		try {
			zipFile = new ZipFile(zipPath);
			//获取压缩文件中所有条目
			Enumeration<ZipEntry> entries = zipFile.getEntries();
			if(entries!=null) {
				while(entries.hasMoreElements()) {
					//压缩文件条目转为文件或文件夹
					ZipEntry zipEntry = entries.nextElement();
					//获取输入流
					InputStream ins = zipFile.getInputStream(zipEntry);
					BufferedInputStream bis = new BufferedInputStream(ins);
					File unzipFile = new File(destPath+File.separator+zipEntry.getName());
					if(zipEntry.isDirectory()) {
						unzipFile.mkdirs();
						continue;
					} 
					
					File pf = unzipFile.getParentFile();
					if(pf!=null && !pf.exists()) {
						pf.mkdirs();
					}
					unzipFile.createNewFile();
					FileOutputStream fos = new FileOutputStream(unzipFile);
					BufferedOutputStream bos = new BufferedOutputStream(fos);
					//输出流写文件
					while((len=bis.read(buff, 0, 1024))!=-1) {
						bos.write(buff, 0, len);
					}
					bos.flush();
					fos.close();
					bos.close();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
		
	}
	
	/**
	 * 获取解压缩文件基路径
	 * @param zipPath
	 * @return 
	 */
	private static String getUnzipBasePath(File zipPath) {
		return zipPath.getParentFile().getAbsolutePath();
	}
	
	/**
	 * 压缩单个文件
	 * @param destPath 压缩文件保存路径
	 * @param srcPath 待压缩文件路径
	 */
	private static void zipFile(String destPath, String srcPath) {
		zipFiles(destPath, srcPath);
	}
	/**
	 * 压缩多个文件
	 * @param srcPath
	 * @param zipPath
	 */
	private static void zipFiles(String destPath, String...srcPaths) {
		if(StringUtils.isBlank(destPath)) {
			File srcFile0 = new File(srcPaths[0]);
			destPath = srcFile0.getParentFile().getAbsolutePath()+File.separator+srcFile0.getName()+"等.zip";
		}
		File zipFile = new File(destPath);
		FileOutputStream fos = null;
		try {
			zipFile.createNewFile();
			zipFile.mkdirs();
			fos = new FileOutputStream(zipFile);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
		//获取输出流
		ZipOutputStream zipOs = new ZipOutputStream(fos);
		//循环将多个文件转为压缩文件条目
		for(String srcPath : srcPaths) {
			if(StringUtils.isBlank(srcPath)) {
				throw new RuntimeException("待压缩文件路径不可为空!");
			}
			File srcFile = new File(srcPath);
			try {
				ZipEntry zipEntry = new ZipEntry(srcFile.getName());
				zipOs.putNextEntry(zipEntry);
				//获取输入流
				FileInputStream fis = new FileInputStream(srcFile);
				int len;
				byte[] buff = new byte[1024];
				//输入/输出流对拷
				while((len=fis.read(buff))!=-1) {
					zipOs.write(buff, 0, len);
				}
				fis.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				throw new RuntimeException();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException();
			}
		}
		try {
			zipOs.flush();
			zipOs.close();
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	
	/**
	 * 压缩文件夹
	 * @param destPath 压缩文件保存路径
	 * @param srcPath 待压缩文件夹路径
	 */
	private static void zipFolder(String destPath, String srcPath) {
		File srcFile = new File(srcPath);
		//如压缩文件保存路径为空,则默认保存路径
		if(StringUtils.isBlank(destPath)) {
			destPath = srcFile.getParent()+File.separator+srcFile.getName()+".zip";
		}
		FileOutputStream fos = null;
		ZipOutputStream zipOs = null;
		try {
			fos = new FileOutputStream(destPath);
			zipOs = new ZipOutputStream(fos);
			//递归往压缩文件中添加文件夹条目
			zipFolder(srcFile, srcFile, zipOs);
			zipOs.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			throw new RuntimeException();
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	
	/**
	 * 递归往压缩文件中添加文件夹条目
	 * @param srcFile 待压缩文件夹路径
	 * @param baseFile 
	 * @param zipOs
	 */
	private static void zipFolder(File srcFile, File baseFile, ZipOutputStream zipOs) {
		int len;
		byte[] buff = new byte[1024];
		if(srcFile.isDirectory()) {
			//针对空文件夹需要特殊处理,需要往Entry中放入"/"+文件夹名+"/"项
			try {
				zipOs.putNextEntry(new ZipEntry(srcFile.getAbsolutePath().replaceFirst(baseFile.getParentFile().getAbsolutePath().replaceAll("\\\\", "\\\\\\\\"), "")+"/"));
				zipOs.closeEntry();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException();
			}
			//获取当前文件夹下文件列表
			File[] fileLists = srcFile.listFiles();
			if(fileLists!=null && fileLists.length>0) {
				for (int i = 0; i < fileLists.length; i++) {
					//递归往压缩文件中添加文件夹条目
					zipFolder(fileLists[i], baseFile, zipOs);
				}
			}
		} else {
			//文件处理比较简单,直接放入Entry
			try {
				FileInputStream fis = new FileInputStream(srcFile);
				zipOs.putNextEntry(new ZipEntry(getRelativePath(baseFile.getAbsolutePath(), srcFile)));
				while((len=fis.read(buff))!=-1) {
					zipOs.write(buff, 0, len);
				}
				zipOs.closeEntry();
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException();
			}
		}
	}
	
	/**
	 * 获取相对基路径的相对路径
	 * @param basePath
	 * @param file
	 * @return
	 */
	private static String getRelativePath(String basePath, File file) {
		if(!basePath.equalsIgnoreCase(file.getAbsolutePath())) {
			return getRelativePath(basePath, file.getParentFile())+File.separator+file.getName();
		} else {
			return file.getName();
		}
	}
	
}

转载于:https://my.oschina.net/u/213148/blog/177250

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值