添加 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的功能,学习了!!!
谢谢支持!