欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-27 14:21:22
...

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

对于压缩文件的下载,可查看我的另一篇博文(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