依赖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; } } }