提示:
本文简单介绍介绍了一下JDK中的zip接口,但JDK自带的zip操作接口非常不完善,既不支持中文,也不支持密码,所以可用性不高。
如果您有在Java语言环境中处理zip压缩文件的需要,推荐采用zip4j这一开源项目,zip4j支持多种加密和压缩算法,采用unicode编码,所以也支持中文,其它方面也是非常优秀,可以说是功能强大。
详见另一篇博客:
http://blog.csdn.net/zhangyihui1986/article/details/7921376
最近由于工作需要,对Java语言下的ZIP和RAR解压和压缩作了一些了解,现记录一下,以备不时之需,如果能帮到各位朋友,自是大佳。
JDK自带的ZIP包解压ZIP压缩文件:
package com.ninemax.demo.zip; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; /** * 压缩指定的文件或目录 * 解压指定的压缩文件(仅限ZIP格式). * 采用JDK1.6,不依赖其它开源项目 * @author zyh */ public class ZipUtil { /** * 将指定文件或者指定目录下的所有文件压缩并生成指定路径的压缩文件. * 如果压缩文件的路径或父路径不存在, 将会自动创建. * @param srcFile 将要进行压缩的文件或目录 * @param destfFile 最终生成的压缩文件的路径 * @throws IOException */ public static void zipFile(String srcFile,String destFile) throws IOException { zipFile(new File(srcFile), new File(destFile)); } /** * 将指定文件或目录下的所有文件压缩并生成指定路径的压缩文件. * 如果压缩文件的路径或父路径不存在, 将会自动创建. * @param srcFile 将要进行压缩的文件或目录 * @param destFile 最终生成的压缩文件的路径 * @throws IOException */ public static void zipFile(File srcFile,File destFile) throws IOException { zipFile(srcFile, FileUtils.openOutputStream(destFile)); } /** * 将指定文件或目录下的所有文件压缩并将流写入指定的输出流中. * * @param srcFile 将要进行压缩的目录 * @param outputStream 用于接收压缩产生的文件流的输出流 */ private static void zipFile(File srcFile,OutputStream outputStream) { zipFile(srcFile, new ZipOutputStream(outputStream)); } /** * 将指定目录下的所有文件压缩并将流写入指定的ZIP输出流中. * * @param srcFile 将要进行压缩的目录 * @param zipOut 用于接收压缩产生的文件流的ZIP输出流 */ private static void zipFile(File srcFile,ZipOutputStream zipOut) { try { doZipFile(srcFile,zipOut, ""); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(zipOut); } } /** * 压缩文件或目录到指定ZipOutputStream * @param srcFile 指定文件或者目录 * @param zipOut 指定ZipOutputStream输出流 * @param ns 文件组织到ZIP文件时的路径 * @throws IOException */ private static void doZipFile(File srcFile, ZipOutputStream zipOut, String ns) throws IOException { if (srcFile.isFile()) { zipOut.putNextEntry(new ZipEntry(ns + srcFile.getName())); InputStream is = FileUtils.openInputStream(srcFile); try { IOUtils.copy(is, zipOut); } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(is); } return; } for (File file : srcFile.listFiles()) { String entryName = ns + file.getName(); if (file.isDirectory()) { entryName += File.separator; zipOut.putNextEntry(new ZipEntry(entryName)); } doZipFile(file, zipOut, entryName); } } /** * 将指定的压缩文件解压到指定的目标目录下. * 如果指定的目标目录不存在或其父路径不存在, 将会自动创建. * * @param zipFile 将会解压的压缩文件 * @param destFile 解压操作的目录 */ public static void unzipFile(String zipFile,String destFile) throws IOException { unzipFile(new File(zipFile), new File(destFile)); } /** * 将指定的压缩文件解压到指定的目标目录下. * 如果指定的目标目录不存在或其父路径不存在, 将会自动创建. * * @param zipFile 将会解压的压缩文件 * @param destFile 解压操作的目录目录 */ public static void unzipFile(File zipFile,File destFile) throws IOException { unzipFile(FileUtils.openInputStream(zipFile), destFile); // doUnzipFile(new ZipFile(zipFile), destFile); } public static void doUnzipFile(ZipFile zipFile,File dest) throws IOException { if (!dest.exists()) { FileUtils.forceMkdir(dest); } Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); File file = new File(dest, entry.getName()); if (entry.getName().endsWith(File.separator)) { FileUtils.forceMkdir(file); } else { OutputStream out = FileUtils.openOutputStream(file); InputStream in = zipFile.getInputStream(entry); try { IOUtils.copy(in, out); } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(out); } } } zipFile.close(); } /** * 将指定的输入流解压到指定的目标目录下. * * @param is 将要解压的输入流 * @param destFile 解压操作的目标目录 * @throws IOException */ public static void unzipFile(InputStream is,File destFile) throws IOException { try { if (is instanceof ZipInputStream) { doUnzipFile((ZipInputStream) is,destFile); } else { doUnzipFile(new ZipInputStream(is), destFile); } } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(is); } } /** * * @param zipInput * @param dest * @throws IOException */ private static void doUnzipFile(ZipInputStream zipInput, File dest) throws IOException { if (!dest.exists()) { FileUtils.forceMkdir(dest); } for (ZipEntry entry; (entry = zipInput.getNextEntry()) != null;) { String entryName = entry.getName(); File file = new File(dest, entry.getName()); if (entryName.endsWith(File.separator)) { FileUtils.forceMkdir(file); } else { OutputStream out = FileUtils.openOutputStream(file); try { IOUtils.copy(zipInput, out); } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(out); } } zipInput.closeEntry(); } } // 测试 public static void main(String[] args) { try { // zipFile("M:\\ZIP\\test\\tempZIP", "M:\\ZIP\\test\\bbc.zip"); unzipFile("M:\\ZIP\\test\\bbc.zip", "M:\\ZIP\\test\\bb\\"); } catch (IOException e) { e.printStackTrace(); } } }
注:1、详细情况请参照JDK文档
2、JDK自身的ZIP包不支持中文,所以网上有很多介绍Apache下的解决方案,此处不作描述,文章太长了就更加臭了,另起一篇写。
3、不支持密码,网上另有支持密码的项目,如果可能,另起文章介绍吧!
Java操作带密码的ZIP文件请参照:
http://blog.csdn.net/zhangyihui1986/article/details/7724229