Java实现Zip的压缩和解压

jdk 1.6 环境下使用 java.util.zip.* 相关的类会存在中文乱码或者读取中文文件出错的问题,所以使用了 ant.jar 库里面的部分类,见代码import部分

package zip;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

public class ZipUtils {
	
	private static final int BUFFER = 1024;  
	private static final String sun_jnu_encoding = System.getProperty("sun.jnu.encoding");
	private static final String file_encoding = System.getProperty("file.encoding");
	
	private static final String encoding = (sun_jnu_encoding == null) ? //
												(file_encoding == null ? "GBK" : file_encoding)//
														: sun_jnu_encoding;//
	
	/**
	 * decompress the zip file (corresponding the zipFilePath) to
	 * the assigned directory represented as destDirPath
	 * the name of the result file is same as the name of zip File
	 * 
	 * @param zipFilePath full path of zip file
	 * @param destDirPath directory which contains the result
	 * @throws IOException
	 */
	public static void unZip(String zipFilePath, String destDirPath)
			throws IOException {
		
		if(zipFilePath == null || destDirPath == null){
			throw new NullPointerException("the path of ZipFile and destination directory both are not Null");
		}
		
		ZipFile zipFile = new ZipFile(zipFilePath);
		File destDir = new File(destDirPath);
		forceMkdir(destDir);
		
		byte[] buf = new byte[BUFFER];
		int len = 0;
		Enumeration<?> entries = zipFile.getEntries();
		while(entries.hasMoreElements()){
			ZipEntry nextEntry = (ZipEntry) entries.nextElement();
			String zipEntryName = nextEntry.getName();
			//if the ZipEntry is directory, make directory
			//else, wirte the file
			File file = new File(destDir, zipEntryName);
			if(nextEntry.isDirectory()){
				forceMkdir(file);
			}
			else{
				InputStream zin = zipFile.getInputStream(nextEntry);
				if(!file.getParentFile().exists()){
					forceMkdir(file.getParentFile());
				}
				FileOutputStream fout = new FileOutputStream(file);
				while( (len = zin.read(buf)) != -1){
					fout.write(buf, 0, len);
				}
				fout.close();
				zin.close();
			}
		}
	}
	
	/**
	 * compress a target (file or directory) to a zip file
	 * that it's name is same as the name of target,
	 * and it is saved in the current path (exists under the 
	 * same directory with the target)
	 * 
//	 * @param srcFilePath the full path of target file or directory
	 * @throws IOException
	 */
	public static void zip(String srcFilePath) throws IOException{
		if(srcFilePath == null){
			throw new NullPointerException();
		}
		File file = new File(srcFilePath);
		
		//the target is folder "aa"  ->   aa.zip
		//the target is file "bb.txt"  ->  bb.zip
		String zipFileName = file.getName().replaceFirst("^(.*?)(?:\\.[\\w]+)?$", "$1.zip");
		
		zip(srcFilePath, new File(file.getParent(), zipFileName).getCanonicalPath());
		
	}
	
	/**
	 * if destZipFilePath is like "c:/a/b", here means the result zip file whose name is
	 * same as the target (file or directory) will be saved under the assigned directory "c:/a/b",
 	 * otherwise when it like "...../a/b/c.zip", the assigned file path is the path of the
 	 * result zip file
	 * @param srcFilePath the full path of target file or directory
	 * @param destZipFilePath 
	 * @throws IOException
	 */
	public static void zip(String srcFilePath, String destZipFilePath) throws IOException{
		if(srcFilePath == null || destZipFilePath == null){
			throw new NullPointerException();
		}
		
		File srcFile = new File(srcFilePath);
		
		if(!srcFile.exists()){
			throw new IllegalArgumentException("srcFilePath can not finded");
		}
		
		ZipOutputStream zout = new ZipOutputStream(new File(destZipFilePath));
		
		zout.setEncoding(encoding);
		
		zipFile( srcFile, zout, "");
		
		zout.close();
	}
	
	private static void zipFile(File srcFile, ZipOutputStream zout, String dir) throws IOException {

		if (srcFile.isDirectory()) {
			File[] files = srcFile.listFiles();
			for (File file:files){
				String zipEntryName = 
						(dir == null || dir.length() == 0) ? srcFile.getName() : (dir + "\\" + srcFile.getName());
				zipFile(file, zout, zipEntryName);
			}
		} else {
			String entryName = null;
			if (!"".equals(dir))
				entryName = dir + "\\" + srcFile.getName();
			else
				entryName = srcFile.getName();
			ZipEntry entry = new ZipEntry(entryName);
			zout.putNextEntry(entry);
			InputStream is = new FileInputStream(srcFile);
			int len = 0;
			while ((len = is.read()) != -1)
				zout.write(len);
			is.close();
		}
	}


	private static void forceMkdir(File directory) throws IOException {
		if (directory.exists()) {
			if (!directory.isDirectory()) {
				String message = "File " + directory + " exists and is "
						+ "not a directory. Unable to create directory.";
				throw new IOException(message);
			}
		} else {
			if (!directory.mkdirs()) {
				// Double-check that some other thread or process hasn't made
				// the directory in the background
				if (!directory.isDirectory()) {
					String message = "Unable to create the not-existed directory " + directory;
					throw new IOException(message);
				}
			}
		}
	}

}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值