北在北方

太白枝头看,花开不计年,杯中浮日月,楼外是青天。

导航

使用commons-compress操作zip文件(压缩和解压缩)

Posted on 2012-06-28 21:46  CN.programmer.Luxh  阅读(18532)  评论(6编辑  收藏  举报

  Apache Commons Compress是一个压缩、解压缩文件的类库。

  可以操作ar, cpio, Unix dump, tar, zip, gzip, XZ, Pack200 and bzip2格式的文件,功能比较强大。

  在这里写两个用Commons Compress把文件压缩成zip和从zip解压缩的方法。

  直接贴上工具类代码:

package cn.luxh.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;


/**
 * Zip文件工具类
 * @author Luxh
 */
public class ZipFileUtil {
	
	/**
	 * 把文件压缩成zip格式
	 * @param files			需要压缩的文件
	 * @param zipFilePath 压缩后的zip文件路径	,如"D:/test/aa.zip";
	 */
	public static void compressFiles2Zip(File[] files,String zipFilePath) {
		if(files != null && files.length >0) {
			if(isEndsWithZip(zipFilePath)) {
				ZipArchiveOutputStream zaos = null;
				try {
					File zipFile = new File(zipFilePath);
					zaos = new ZipArchiveOutputStream(zipFile);
					//Use Zip64 extensions for all entries where they are required
					zaos.setUseZip64(Zip64Mode.AsNeeded);
					
					//将每个文件用ZipArchiveEntry封装
					//再用ZipArchiveOutputStream写到压缩文件中
					for(File file : files) {
						if(file != null) {
							ZipArchiveEntry zipArchiveEntry  = new ZipArchiveEntry(file,file.getName());
							zaos.putArchiveEntry(zipArchiveEntry);
							InputStream is = null;
							try {
								is = new BufferedInputStream(new FileInputStream(file));
								byte[] buffer = new byte[1024 * 5];  
								int len = -1;
								while((len = is.read(buffer)) != -1) {
									//把缓冲区的字节写入到ZipArchiveEntry
									zaos.write(buffer, 0, len);
								}
								//Writes all necessary data for this entry.
								zaos.closeArchiveEntry();  
							}catch(Exception e) {
								throw new RuntimeException(e);
							}finally {
								if(is != null) 
									is.close();
							}
							
						}
					}
					zaos.finish();
				}catch(Exception e){
					throw new RuntimeException(e);
				}finally {
						try {
							if(zaos != null) {
								zaos.close();
							}
						} catch (IOException e) {
							throw new RuntimeException(e);
						}
				}
				
			}
			
		}
		
	}
	
	/**
	 * 把zip文件解压到指定的文件夹
	 * @param zipFilePath   zip文件路径, 如 "D:/test/aa.zip"
	 * @param saveFileDir   解压后的文件存放路径, 如"D:/test/"
	 */
	public static void decompressZip(String zipFilePath,String saveFileDir) {
		if(isEndsWithZip(zipFilePath)) {
			File file = new File(zipFilePath);
			if(file.exists()) {
				InputStream is = null;
				//can read Zip archives
				ZipArchiveInputStream zais = null;
				try {
					is = new FileInputStream(file);
					zais = new ZipArchiveInputStream(is);
					ArchiveEntry  archiveEntry = null;
					//把zip包中的每个文件读取出来
					//然后把文件写到指定的文件夹
					while((archiveEntry = zais.getNextEntry()) != null) {
						//获取文件名
						String entryFileName = archiveEntry.getName();
						//构造解压出来的文件存放路径
						String entryFilePath = saveFileDir + entryFileName;
						byte[] content = new byte[(int) archiveEntry.getSize()];
						zais.read(content);
						OutputStream os = null;
						try {
							//把解压出来的文件写到指定路径
							File entryFile = new File(entryFilePath);
							os = new BufferedOutputStream(new FileOutputStream(entryFile));
							os.write(content);
						}catch(IOException e) {
							throw new IOException(e);
						}finally {
							if(os != null) {
								os.flush();
								os.close();
							}
						}
						
					}
				}catch(Exception e) {
					throw new RuntimeException(e);
				}finally {
						try {
							if(zais != null) {
								zais.close();
							}
							if(is != null) {
								is.close();
							}
						} catch (IOException e) {
							throw new RuntimeException(e);
						}
				}
			}
		}
	}
	
	/**
	 * 判断文件名是否以.zip为后缀
	 * @param fileName        需要判断的文件名
	 * @return 是zip文件返回true,否则返回false
	 */
	public static boolean isEndsWithZip(String fileName) {
		boolean flag = false;
		if(fileName != null && !"".equals(fileName.trim())) {
			if(fileName.endsWith(".ZIP")||fileName.endsWith(".zip")){
				flag = true;
			}
		}
		return flag;
	}
	
}

  再来测试一下:

package cn.luxh.test;

import java.io.File;

import org.junit.Test;

import cn.luxh.utils.ZipFileUtil;

/**
 * 测试ZipFileUtil的压缩和解压缩方法
 * @author Luxh
 */
public class ZipFileUtilTest {
	
	@Test
	public void testCompressFiles2Zip() {
		//存放待压缩文件的目录
		File srcFile = new File("D:/test");
		//压缩后的zip文件路径
		String zipFilePath = "d:/test2/test.zip";
		if(srcFile.exists()) {
			File[] files = srcFile.listFiles();
			ZipFileUtil.compressFiles2Zip(files, zipFilePath);
		}
	}
	
	@Test
	public void testDecompressZip()  {
		//压缩包所在路径
		String zipFilePath = "d:/test2/test.zip";
		//解压后的文件存放目录
		String saveFileDir = "d:/test2/";
		//调用解压方法
		ZipFileUtil.decompressZip(zipFilePath, saveFileDir);
	}
}