基于JDK API实现文件的压缩与解压

在实际开发过程中,会经常遇到下载附件或者导出报表的情况,有时候文件会比较多,用户更希望多个文件可以一起打包进行下载。这时就需要实现两部分功能:一部分是多个文件的打包处理,一部分是压缩文件的下载功能。

对于压缩文件的下载,可查看我的另一篇博文(SpringMVC下打包文件的下载),本文主要提供多个文件的压缩与解压的例子。样例完全基于JDK自带的IO流处理类,主要相关类为ZipInputStream和ZipOutputStream,使用JDK API已经能够满足压缩与解压的需求。我看网上有不少提到压缩中文乱码的问题,建议用ant.jar中包的ZIP处理类进行处理,我进行了相关测试:使用JDK1.6进行压缩会出现压缩包中的文件中文名乱码,但是使用JDK1.7或者JDK1.8不会乱码。

所以本样例正常运行需要使用JDK1.7+的版本。

另注:本样例仍然有个问题有待解决:我分别使用txt文件、excel文件、word文件进行压缩测试,压缩正常,使用WinRAR工具解压后文件也能正常查看。但是使用JDK的IO流解压后,只有txt文件查看正常,excel与word文件都损坏了,无法正常查看。这个问题仍未找到原因与解决方案,若有大神告知,感激不尽。

下面直接上代码:
一、压缩与解压工具类

ZipUtils.java 

package research.j2se.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 使用JDK自带的Zip处理类进行文件的压缩与解压
 *
 */
public class ZipUtils {
	
	/**
	 * 压缩文件(一个或多个)到指定压缩包
	 */
	public static void zip( String targetFilePath, String ... sourceFilePaths){
		if( sourceFilePaths == null || sourceFilePaths.length == 0 ){
			return;
		}
		try {
			File targetFile = new File(targetFilePath);
			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(targetFile));
			BufferedInputStream bis = null;
			byte [] buffer = new byte[512];
			for( int i = 0; i < sourceFilePaths.length; i++ ){
				File sourceFile = new File(sourceFilePaths[i]);
				if( sourceFile.exists() ){
					//目标文件不存在则创建文件
					if( ! targetFile.exists() ){
						targetFile.createNewFile();
					}
					String sourceFileName = sourceFile.getName();
					ZipEntry entry = new ZipEntry(sourceFileName);
					//设置压缩包的入口
					zos.putNextEntry(entry);
					bis = new BufferedInputStream(new FileInputStream(sourceFile));
					while( bis.read(buffer) != -1){
						zos.write(buffer);
					}
				}
			}
			bis.close();
			zos.flush();
			zos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 解压文件到指定目录
	 */
	public static void unzip(String targetDirPath, String ... sourceFilePaths){
		if( sourceFilePaths == null || sourceFilePaths.length == 0 ){
			return;
		}
		//解压目录不存在则创建
		File targetDir = new File(targetDirPath);
		if( ! targetDir.exists() ){
			targetDir.mkdirs();
		}
		try {
			byte [] buffer = new byte[512];
			for( int i = 0; i < sourceFilePaths.length; i++ ){
				File sourceFile = new File(sourceFilePaths[i]);
				ZipInputStream zis = new ZipInputStream(new FileInputStream(sourceFile));
				ZipEntry entry = null;
				//遍历压缩文件的各个入口
				while( (entry=zis.getNextEntry()) != null ){
					String fileName = entry.getName();
					//创建对应的文件
					File file = new File(targetDirPath+File.separator + fileName);
					if( ! file.exists() ){
						file.createNewFile();
					}
					//进行文件的写入
					BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file,true));
					while( zis.read(buffer) != -1 ){
						bos.write(buffer);
					}
					zis.closeEntry();
					bos.flush();
					bos.close();
				}
				zis.close();
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch( Exception e ){
			e.printStackTrace();
		}
	}
	
}

 二、压缩与解压测试类

JdkZipUtilsTest.java

package research.j2se.io;

import junit.framework.TestCase;
import research.j2se.io.ZipUtils;

/**
 * jdk压缩解压工具类测试
 */
public class JdkZipUtilsTest
    extends TestCase
{
   
	/**
	 * 测试压缩文件
	 */
    public void testZip()
    {
    	String targetFilePath = "src/main/resources/ziptarget/zip/压缩.zip";
    	String sourceFilePath1 = "src/main/resources/zipsource/unzip/测试1.xlsx";
    	String sourceFilePath2 = "src/main/resources/zipsource/unzip/测试2.txt";
    	String sourceFilePath3 = "src/main/resources/zipsource/unzip/测试3.docx";
        ZipUtils.zip(targetFilePath, sourceFilePath1,sourceFilePath2,sourceFilePath3);
    }
    
    /**
     * 测试解压文件(这里Excel文件解压无法打开,使用解压工具可以打开)
     */
    public void testUnzip(){
    	String targetDirPath = "src/main/resources/ziptarget/unzip";
    	String sourceFilePath1 = "src/main/resources/zipsource/zip/压缩.zip";
    	ZipUtils.unzip(targetDirPath, sourceFilePath1);
    }
}

 

本样例测试通过。若要查看完整源码,可访问:https://github.com/wdmcygah/research-J2SE.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值