本文简单介绍介绍了一下JDK中的zip接口,但JDK自带的zip操作接口非常不完善,既不支持中文,也不支持密码,所以可用性不高。
如果您有在Java语言环境中处理zip压缩文件的需要,推荐采用zip4j这一开源项目,zip4j支持多种加密和压缩算法,采用unicode编码,所以也支持中文,其它方面也是非常优秀,可以说是功能强大。
最近由于工作需要,对Java语言下的ZIP和RAR解压和压缩作了一些了解,现记录一下,以备不时之需,如果能帮到各位朋友,自是大佳。
首先说说ZIP格式:
JDK本身就已经提供了操作ZIP文件的接口(在java.util.zip包下),这些接口使用起来很简单,该包下主要涉及了
ZipEntry // 此类用于表示 ZIP 文件条目
ZipFile // 此类用于从 ZIP 文件读取条目
ZipInputStream // 此类为读取 ZIP 文件格式的文件实现输入流
ZipOutputStream // 此类为以 ZIP 文件格式写入文件实现输出流
等几个类,其它的类有些跟校验有关,还有一些不明白了,基本使用中没有用到。
其中ZipEntry代表ZIP文件中一条项目(包括目录和文件),ZipFile则表示一个zip压缩文件,ZipFile类中提供了获取其代表文件中的所有Entry的方法,通过这些方法我们可以取得第一条ZipEntry,该对象中有我们需要的信息,可以通过读写流操作将其从压缩文件中抽出,并写到本地磁盘,完成操作也就表示完成了ZIP文件的解压。
ZipInputStream 表示ZIP文件的输入流,通过该类也可以完成解压,其中也有获取ZipEntry的方法,同ZipFile类似可以通过流的读写完成解压。
ZipOutputStream 表示ZIP文件的输出流,可以完成ZIP压缩,也是通过其相关方法将新建ZipEntry(目录或文件)添加进输出流,然后同样通过流的读写将本地磁盘文件写进ZIP压缩文件(如果是目录则不需要流操作,仅需将ZipEntry添加进输出流即可),最后输出到磁盘。
在解压过程中有一个问题需要注意,就是压缩文件中含有目录嵌套这种情况,其实ZipEntry中有一个方法isDirectory(),但我试了一下,不论何种情况该方法都反回false,不知道是不是自己有什么 地方没有做对,于是就想用一种比较笨的方式创建目录:如果当前ZipEntry的name(可以能过getName()获得)以File.separator结尾说明该Entry是个目录,将其创建,如果不是则将其抽出。如果哪位有好的方式请赐教。
说多了也没啥用,个人理解也不是很透彻,下面是一个比较简单的示例,仅仅是几个API的使用,不过仍然简单地完成了压缩和解压缩,如果您在关注,希望能起到点抛砖引玉的作用。
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);
}
}