7zip(下面简称7z)是由Igor Pavlov所开发的一种压缩格式,主要使用的压缩算法是LZMA/LZMA2。7z是一种压缩比非常高的格式,这与其压缩算法LZMA有直接关系,所以很多大文件都是用7z进行压缩的,比如游戏之类;高压缩比并非只有好处,就是7z的压缩速度非常慢(解压速度尚可)-当然,所有压缩算法都类似:高压缩比往往是解压速度慢,这实际上可以理解为CPU与内存/硬盘之间的trade off,后面我会详细聊一下压缩背后的原理与算法。

Commons Compress是少数支持7z压缩/解压的JAVA库(据我所知除了Commons Compress就只有XZ Utils了),其API也相对友好。

与zip格式不同,commons compress在解压7z时只提供了SevenZFile类,并未提供SevenZInputStream进行逐个解压的接口,这与7z文件的格式、算法都有关系,这里不再展开说明了。

好了,废话不多说,我们进入主题:

查看7z中的所有文件

我们可以通过sevenZFile.getEntries()查看7z中的所有文件,包括文件名等属性都可以在SevenZArchiveEntry中查看。相关代码如下:

SevenZFile sevenZFile = new SevenZFile(new File("/root/test.7zip"));

final Iterable entries = sevenZFile.getEntries();

for (SevenZArchiveEntry entry : entries) {

System.out.println(entry.getName());

System.out.println(entry.getCompressedSize()); // 文件压缩后大小 System.out.println(entry.getSize()); // 文件大小}

解压全部文件

解压全部文件时可以通过sevenZFile.getNextEntry遍历所有文件并进行解压,比如我要将位于/root/test.7zip位置的文件,全部解压到/tmp/output目录下,代码如下:

try (SevenZFile sevenZFile = new SevenZFile(new File("/root/test.7zip"))) {

byte[] buffer = new byte[4096];

SevenZArchiveEntry entry;

while ((entry = sevenZFile.getNextEntry()) != null) {

if (entry.isDirectory()) {

continue;

}

File outputFile = new File("/tmp/output/" + entry.getName());

if (!outputFile.getParentFile().exists()) {

outputFile.getParentFile().mkdirs();

}

try (FileOutputStream fos = new FileOutputStream(outputFile)) {

while (sevenZFile.read(buffer) > 0) {

fos.write(buffer);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

解压特定文件

可以通过sevenZFile.getEntries(),获得所有文件后,通过遍历找到需要解压的zip文件,调用SevenZFile.getInputStream获取其InputStream,进行解压,比如需要将/root/test.7zip压缩包中,文件名为targetFile的文件,解压到/tmp/output/targetFile文件中,代码如下:

SevenZFile sevenZFile = new SevenZFile(new File("/root/test.7zip"));

final Iterable entries = sevenZFile.getEntries();

InputStream inputStream = null;

for (SevenZArchiveEntry entry : entries) {

if (entry.getName().equals("targetFile")) {

inputStream = sevenZFile.getInputStream(entry);

}

}

// 读取input stream即可完成解压byte[] buffer = new byte[4096];

File outputFile = new File("/tmp/output/targetFile");

try (FileOutputStream fos = new FileOutputStream(outputFile)) {

while (inputStream.read(buffer) > 0) {

fos.write(buffer);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

注意:7z解压特定文件(也叫随机访问)是Compress的1.20版本以后才支持的特性

解压内存中的文件

Compress的所有压缩,都可以处理硬盘及内存中的文件,7z也不例外,这在网络IO等场景下非常实用,使用也很简单:

// 通过网络IO或其他途径,将7z文件读入内存byte[] data = XXX

SevenZFile sevenZFile = new SevenZFile(new SeekableInMemoryByteChannel(data));

注意:如果文件较大时,读入内存可能消耗很多内存资源

解压分卷7z文件

分卷文件解压也十分简单:

SevenZFile sevenZFile = new SevenZFile(MultiReadOnlySeekableByteChannel

.forFiles(new File("/root/test.7z.001"), new File("/root/test.7z.002")));

// 剩余代码类似XXX

注意:传入MultiReadOnlySeekableByteChannel.forFiles的7z分卷文件,需要按照正确的顺序排列

压缩

Compress压缩7z文件,是通过xz utils实现的,并且xz在Compress的POM中是可选依赖,因此,如果要使用Compress压缩7z文件,需要在POM中手动依赖xz utils

org.tukaani

xz

1.8

压缩功能相对解压,没有那么多选择,具体可以参见下面代码中的注释:

File dir = new File("/root/dir");

File output = new File(dir, "test.7z");

final Date accessDate = new Date();

final Calendar cal = Calendar.getInstance();

cal.add(Calendar.HOUR, -1);

final Date creationDate = cal.getTime();

try (SevenZOutputFile outArchive = new SevenZOutputFile(output)) {

// 在7z中创建一个文件夹 SevenZArchiveEntry entry = outArchive.createArchiveEntry(dir, "foo/");

outArchive.putArchiveEntry(entry);

outArchive.closeArchiveEntry();

// 创建一个新的文件entry entry = new SevenZArchiveEntry();

// 文件命名 entry.setName("foo/bar");

// 文件创建时间、最后修改时间 entry.setCreationDate(creationDate);

entry.setAccessDate(accessDate);

outArchive.putArchiveEntry(entry);

// 这里是文件要写入的数据,可能是从其他文件中读取到的,也可以自己操作 byte[] data = XXX

outArchive.write(new byte[0]);

outArchive.closeArchiveEntry();

// 写入第二个文件,与第一个类似 entry = new SevenZArchiveEntry();

entry.setName("xyzzy");

outArchive.putArchiveEntry(entry);

outArchive.write(0);

outArchive.closeArchiveEntry();

// 完成7z文件写入后,需要调用finish outArchive.finish();

}

总结

以上就是Commons Compress处理7z格式的常用接口,同样的,如果使用中遇到了什么问题或bug,欢迎到Compress的JIRA上提问题,当然也是需要用英语提问的:)- ASF JIRA​issues.apache.org

java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件相关推荐

  1. java 分卷压缩_Apache Commons Compress介绍-Zip压缩解压

    Zip格式应该是最出名的压缩格式之一了,zlib.gzip这些辈分很老的库大家应该都用过,甚至大部分其他格式的压缩库,都可以处理zip格式.Commons Compress当然也少补了对zip格式的支 ...

  2. java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/zip/ZipFile

    poi4.0.0读取excel文件时报java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/zip/ZipFile ...

  3. Linux世界的三种压缩解压方式,zip/unzip方式压缩解压、tar方式压缩解压、jar方式压缩解压暨shopt extglob反选示例

    Linux世界的三种压缩解压方式,zip/unzip方式压缩解压.tar方式压缩解压.jar方式压缩解压暨shopt extglob反选示例 zip/unzip方式.tar方式压缩解压是Linux中的 ...

  4. java关键字 valotile_Java内存模型-jsr133规范介绍,java中volatile关键字的含义

    最近在看<深入理解Java虚拟机:JVM高级特性与最佳实践>讲到了线程相关的细节知识,里面讲述了关于java内存模型,也就是jsr 133定义的规范. 系统的看了jsr 133规范的前面几 ...

  5. zip包怎么解压oracle,使用jar与zip压缩解压文件的区别

    使用jar命令压缩和解压文件不会继承原来的权限,切记! 而使用zip/unzip压缩解压文件则会保留文件原来的权限等信息,因此使用压缩解压的时候尽量使用专业的工具 下面是测试内容和结果: 1.首先确认 ...

  6. 解压命令linux tgz,linux常用压缩解压命令:tar,tgz,gzip,zip,rar

    一,tar (一) tar压缩命令tar -cvf examples.tar files|dir #说明: -c, --create  create a new archive 创建一个归档文件 -v ...

  7. kafka java代码横杠_Apache Beam Kafkaio获取java.lang.illegalargumentException:无法序列化KafkaunBoundedSource...

    我正在建造一条从卡夫卡读取的阿帕奇光束管道 KafkaIO 但我不知道如何解决序列化问题. 如何使用Kafkaio: this.pipeline .apply("ReadFromKafka& ...

  8. java中commons-net包_Apache commons net 包介绍和简单使用详解

    Apache commons net 项目中封装了各种网络协议的客户端,支持的协议包括: ·        FTP ·        NNTP ·        SMTP ·        POP3 ...

  9. java length()函数_小猿圈介绍java函数式编码结构及优势

    对于java大家都已经不陌生了吧,今天小猿圈Java讲师就分享一篇关于java函数式编码结构及优势的知识点,希望对于学习java的你有一定的帮助,想学习就需要积累. 探讨三种下一代JVM语言:Groo ...

最新文章

  1. php getconfig,PHP: tidy::getConfig - Manual
  2. flutter系列InheritedWidget介绍
  3. Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集
  4. excel用警员姓名查找警号信息
  5. Xception: DeepLearning with Depthwise Separable Convolutions2017Google【论文理解】
  6. 计算机二级(C语言)备考
  7. pom文件无法加载ojdbc14-10.2.0.4.0.jar
  8. 如何批量修改图片尺寸而不变形?
  9. 树莓派使用433Mhz射频无线收发
  10. 有关XLS文件的读取
  11. 基于Java的亚马逊“手机”评论爬虫的情感分类分析
  12. 想学.Net,只要功夫深,铁柱磨成针
  13. 有一位后代曾忏悔:他的祖父继承家里的淫业,到了他父亲那一代,果报现前
  14. 【Unity】新手初学Animation实现人物移动
  15. 阿里云服务器优惠以及采购流程
  16. 硬盘的文件格式变为RAW格式
  17. u盘中的android文件夹图标不显示,U盘中文件夹怎么设置自定义图标而不变样
  18. Web前端之jQuery库
  19. 一位IT新人对工作计划的心得体会
  20. UE4 动画重定向之使用同一套骨骼

热门文章

  1. STM32 基础系列教程 34 - Lwip_tcp_server
  2. 1、C语言面试笔试---变量定义和声明
  3. kdir测试软件,[OK210开发板体验]入门篇(4)编程入门(NFS登录、驱动入门)
  4. FPGA篇(五)Capture导出FPGA引脚分配和端口定义
  5. HDU 4609 3-idiots
  6. tomcat 部署 RESTful 服务实例
  7. Linux下的Nano命令
  8. centos6.5_x64远程链接输入正确的账号密码无法登陆
  9. Android系统启动过程全解析
  10. 使用Chrome工具来分析页面的绘制状态