使用 commons compress 实现 zip 文件解压

本文将介绍怎样利用 apache commons compress 库解压 zip 文件

添加依赖

添加 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 类,下面将分别进行简单介绍。

ZipArchiveInputStream 

该类实现一个可以读取 zip 压缩文件的输入流。在 Apache Commons Compress 中,它透明地支持 zip64 扩展,从而支持大于 4GB 或大于 65536 项的单个条目和归档。

从文件读取时,首选 ZipFile 类,因为 ZipArchiveInputStream 受限制,因为在返回条目之前无法读取中央目录头。特别是 ZipArchiveInputStream:

  • 可能会返回根本不属于中央目录的条目,并且不应将其视为存档的一部分。

  • 可能会返回多个具有相同名称的条目。

  • 不会返回内部或外部属性。

  • 可能返回不完整的额外字段数据。

  • 如果档案使用数据描述符功能,则可能会返回未知的条目大小和CRC值,直到到达下一个条目为止。

ZipArchiveEntry 

该扩展增加了对额外字段的更好处理,并提供了对内部和外部文件属性的访问。

额外的数据应遵循 APPNOTE.TXT 的建议:

  • 额外的字节数组由一系列额外的字段组成

  • 每个额外的字段均以两个字节的标头 ID 开头,后跟两个字节的序列,以保留其余数据的长度。

不能由上述规则解析的任何额外数据将被视为“不可解析的”额外数据,并且由此类的方法进行区别对待。 如果尝试读取或写入不符合建议的额外数据,则Apache Commons Compress 1.1 之前的版本将引发异常。

此类不是线程安全的

总结:ZipArchiveInputStream 类用来读取 zip 压缩文件,读取文件的同时就已经对文件进行了解压。我们需要做的是递归或循环调用 getNextZipEntry() 方法获取 ZipArchiveInputStream 类中的 ZipArchiveEntry。然而,一个 ZipArchiveEntry 表示 zip 压缩文件中一个文件或目录。我们就可以根据获取到的 ZipArchiveEntry 创建目录或文件,这样一个 zip 文件就被完整的解压出来了。

少壮不努力,老大徒悲伤。——汉乐府古辞《长歌行》
0 不喜欢
说说我的看法 -
全部评论(

项目中正好需要用到解压zip的功能,学习了!!!

回复:

谢谢支持!

关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号