添加 apache commons compress 的 maven 依赖,如下:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.18</version> </dependency>
下面代码将把 test.zip 压缩文件解压到 tmp 目录,完整代码如下:
package com.huangx.compress.zip;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import java.io.*;
/**
* zip解压
* @author huangxin 2019/12/26
*/
public class ZipDecompress {
public static void main(String[] args) throws Exception {
String basePath = System.getProperty("user.dir");
String source = basePath + "\\apache-commons-Compress\\document\\test.zip";
String target = basePath + "\\apache-commons-Compress\\document\\tmp";
File sourceFile = new File(source);
if(!sourceFile.exists()) {
System.err.println("文件不存在 " + sourceFile);
System.exit(-1);
}
ZipArchiveInputStream inputStream = new ZipArchiveInputStream(
new BufferedInputStream(new FileInputStream(sourceFile)));
ZipArchiveEntry zipArchiveEntry;
while( (zipArchiveEntry = inputStream.getNextZipEntry()) != null) {
BufferedOutputStream outputStream = new BufferedOutputStream(
new FileOutputStream(new File(target + "\\" + zipArchiveEntry.getName())));
byte[] buffer = new byte[1024];
int len;
while((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
outputStream.close();
}
inputStream.close();
System.out.println("finished.");
}
}上面代码中主要关注 ZipArchiveInputStream 和 ZipArchiveEntry 类,下面将分别进行简单介绍。
该类实现一个可以读取 zip 压缩文件的输入流。在 Apache Commons Compress 中,它透明地支持 zip64 扩展,从而支持大于 4GB 或大于 65536 项的单个条目和归档。
从文件读取时,首选 ZipFile 类,因为 ZipArchiveInputStream 受限制,因为在返回条目之前无法读取中央目录头。特别是 ZipArchiveInputStream:
可能会返回根本不属于中央目录的条目,并且不应将其视为存档的一部分。
可能会返回多个具有相同名称的条目。
不会返回内部或外部属性。
可能返回不完整的额外字段数据。
如果档案使用数据描述符功能,则可能会返回未知的条目大小和CRC值,直到到达下一个条目为止。
该扩展增加了对额外字段的更好处理,并提供了对内部和外部文件属性的访问。
额外的数据应遵循 APPNOTE.TXT 的建议:
额外的字节数组由一系列额外的字段组成
每个额外的字段均以两个字节的标头 ID 开头,后跟两个字节的序列,以保留其余数据的长度。
不能由上述规则解析的任何额外数据将被视为“不可解析的”额外数据,并且由此类的方法进行区别对待。 如果尝试读取或写入不符合建议的额外数据,则Apache Commons Compress 1.1 之前的版本将引发异常。
此类不是线程安全的
总结:ZipArchiveInputStream 类用来读取 zip 压缩文件,读取文件的同时就已经对文件进行了解压。我们需要做的是递归或循环调用 getNextZipEntry() 方法获取 ZipArchiveInputStream 类中的 ZipArchiveEntry。然而,一个 ZipArchiveEntry 表示 zip 压缩文件中一个文件或目录。我们就可以根据获取到的 ZipArchiveEntry 创建目录或文件,这样一个 zip 文件就被完整的解压出来了。
项目中正好需要用到解压zip的功能,学习了!!!
谢谢支持!