java zip工具类

依赖jar :apache-ant-1.9.2-bin.zip

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.FilenameFilter;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.List;



import org.apache.commons.lang3.StringUtils;

import org.apache.tools.zip.ZipEntry;

import org.apache.tools.zip.ZipFile;

import org.apache.tools.zip.ZipOutputStream;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.util.Assert;



/**

 * zip工具

 * 用于制作压缩包和解压包

 * @author Sun Qinbo

 * @version 1.0, 2013-7-26

 */

public class ZipUtils {

	private static final Logger log = LoggerFactory.getLogger(ZipUtils.class);

	private ZipOutputStream zipOut;

	private static byte[] buf = new byte[1024];



	/**

	 * 制作压缩包

	 */

	public static void zip(OutputStream out, List<FileEntry> fileEntrys, String encoding) {

		new ZipUtils(out, fileEntrys, encoding);

	}



	/**

	 * 制作压缩包

	 */

	public static void zip(OutputStream out, List<FileEntry> fileEntrys) {

		new ZipUtils(out, fileEntrys, null);

	}



	/**

	 * 根据源目录 制作压缩包

	 * @param srcFiles 源文件目录

	 * @param out 输出文件流

	 * @param filter 文件过滤,不过滤可以为null。

	 * @param parent 压缩包根目录名,不需要可以为null。

	 * @param prefix 文件前缀,不需要可以为null。

	 * @param encoding 编码 ,不设置取系统编码。

	 */



	public static void zip(File[] srcFiles, OutputStream out, FilenameFilter filter, String parent, String prefix, String encoding) {

		Assert.notEmpty(srcFiles);

		List<FileEntry> fileEntrys = new ArrayList<FileEntry>();

		for (int i = 0; i < srcFiles.length; i++) {

			FileEntry fileEntry = new FileEntry(parent, prefix, srcFiles[i], filter);

			fileEntrys.add(fileEntry);

		}

		new ZipUtils(out, fileEntrys, encoding);

	}



	/**

	 * 创建ZipUtils对象

	 * @param out 输出流

	 * @param filter 文件过滤,不过滤可以为null。

	 * @param fileEntrys 源文件名。可以有多个源文件,如果源文件是目录,那么所有子目录都将被包含。

	 */

	protected ZipUtils(OutputStream out, List<FileEntry> fileEntrys, String encoding) {

		Assert.notEmpty(fileEntrys);

		long begin = System.currentTimeMillis();

		log.debug("开始制作压缩包");

		try {

			try {

				zipOut = new ZipOutputStream(out);

				if (!StringUtils.isBlank(encoding)) {

					log.debug("using encoding: {}", encoding);

					zipOut.setEncoding(encoding);

				} else {

					log.debug("using default encoding");

				}

				for (FileEntry fe : fileEntrys) {

					zip(fe.getFile(), fe.getFilter(), fe.getZipEntry(), fe.getPrefix());

				}

			} finally {

				zipOut.close();

			}

		} catch (IOException e) {

			throw new RuntimeException("制作压缩包时,出现IO异常!", e);

		}

		long end = System.currentTimeMillis();

		log.info("制作压缩包成功。耗时:{}ms。", end - begin);

	}



	/**

	 * 压缩文件

	 * @param srcFile 源文件

	 * @param pentry 压缩包根目录名,不需要可以为null。

	 * @param prefix 文件前缀

	 * @throws IOException

	 */

	private void zip(File srcFile, FilenameFilter filter, ZipEntry pentry, String prefix) throws IOException {

		ZipEntry entry;

		if (srcFile.isDirectory()) {

			if (pentry == null) {

				entry = new ZipEntry(srcFile.getName());

			} else {

				entry = new ZipEntry(pentry.getName() + "/" + srcFile.getName());

			}

			File[] files = srcFile.listFiles(filter);

			for (File f : files) {

				zip(f, filter, entry, prefix);

			}

		} else {

			if (pentry == null) {

				entry = new ZipEntry(prefix + srcFile.getName());

			} else {

				entry = new ZipEntry(pentry.getName() + "/" + prefix + srcFile.getName());

			}

			FileInputStream in;

			try {

				log.debug("读取文件:{}", srcFile.getAbsolutePath());

				in = new FileInputStream(srcFile);

				try {

					zipOut.putNextEntry(entry);

					int len;

					while ((len = in.read(buf)) > 0) {

						zipOut.write(buf, 0, len);

					}

					zipOut.closeEntry();

				} finally {

					in.close();

				}

			} catch (FileNotFoundException e) {

				throw new RuntimeException("制作压缩包时,源文件不存在:" + srcFile.getAbsolutePath(), e);

			}

		}

	}



	/**

	 * 解压

	 * @param zipFile 压缩包文件

	 * @param destDir 压缩路径

	 * @param encoding

	 * @author Sun Qinbo

	 */

	public static void unzip(File zipFile, File destDir, String encoding) {

		long begin = System.currentTimeMillis();

		log.debug("开始解压缩包");

		if (destDir.exists() && !destDir.isDirectory()) {

			throw new IllegalArgumentException("destDir is not a directory!");

		}

		ZipFile zip = null;

		InputStream is = null;

		FileOutputStream fos = null;

		File file;

		String name;

		int readed;

		ZipEntry entry;

		try {

			try {

				if (StringUtils.isNotBlank(encoding)) {

					zip = new ZipFile(zipFile, encoding);

				} else {

					zip = new ZipFile(zipFile);

				}

				Enumeration<?> en = zip.getEntries();

				while (en.hasMoreElements()) {

					entry = (ZipEntry) en.nextElement();

					name = entry.getName();

					name = name.replace('/', File.separatorChar);

					file = new File(destDir, name);

					if (entry.isDirectory()) {

						file.mkdirs();

					} else {

						// 创建父目录

						file.getParentFile().mkdirs();

						is = zip.getInputStream(entry);

						fos = new FileOutputStream(file);

						while ((readed = is.read(buf)) > 0) {

							fos.write(buf, 0, readed);

						}

						fos.close();

						is.close();

					}

				}

			} finally {

				if (fos != null) {

					fos.close();

				}

				if (is != null) {

					is.close();

				}

				if (zip != null) {

					zip.close();

				}

			}

		} catch (IOException e) {

			log.error("", e);

		}

		long end = System.currentTimeMillis();

		log.info("解压缩包成功。耗时:{}ms。", end - begin);



	}



	/** 测试 */

	public static void main(String[] args) throws IOException {

		List<FileEntry> fileEntrys = new ArrayList<FileEntry>();

		File[] listFiles = new File("d://test").listFiles();

		for (int i = 0; i < listFiles.length; i++) {

			fileEntrys.add(new FileEntry("", "", listFiles[i]));

		}

		ZipUtils.zip(new FileOutputStream("D://测试_1.zip"), fileEntrys);

		ZipUtils.zip(new File("d://test").listFiles(), new FileOutputStream("D://测试_2.zip"), null, "自定义根目录", "自定义前缀_", "UTF-8");

		ZipUtils.unzip(new File("D://测试_2.zip"), new File("D://测试_2"), null);

	}



	/**

	 * 源文件自定义类型

	 */

	public static class FileEntry {

		private FilenameFilter filter;

		private String parent; // 压缩包内的目录名

		private File file;

		private String prefix; // 压缩文件前缀



		public FileEntry(String parent, String prefix, File file, FilenameFilter filter) {

			this.parent = parent;

			this.prefix = prefix;

			this.file = file;

			this.filter = filter;

		}



		/**

		 * @param parent 压缩包内的目录名

		 * @param file 压缩文件前缀

		 */

		public FileEntry(String parent, File file) {

			this.parent = parent;

			this.file = file;

		}



		public FileEntry(String parent, String prefix, File file) {

			this(parent, prefix, file, null);

		}



		public ZipEntry getZipEntry() {

			if (StringUtils.isBlank(parent)) {

				return null;

			} else {

				return new ZipEntry(parent);

			}

		}



		public FilenameFilter getFilter() {

			return filter;

		}



		public void setFilter(FilenameFilter filter) {

			this.filter = filter;

		}



		public String getParent() {

			return parent;

		}



		public void setParent(String parent) {

			this.parent = parent;

		}



		public File getFile() {

			return file;

		}



		public void setFile(File file) {

			this.file = file;

		}



		public String getPrefix() {

			if (prefix == null) {

				return "";

			} else {

				return prefix;

			}

		}



		public void setPrefix(String prefix) {

			this.prefix = prefix;

		}

	}

}


你可能感兴趣的:(java)