java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件
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 JIRAissues.apache.org
java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件相关推荐
- java 分卷压缩_Apache Commons Compress介绍-Zip压缩解压
Zip格式应该是最出名的压缩格式之一了,zlib.gzip这些辈分很老的库大家应该都用过,甚至大部分其他格式的压缩库,都可以处理zip格式.Commons Compress当然也少补了对zip格式的支 ...
- java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/zip/ZipFile
poi4.0.0读取excel文件时报java.lang.NoClassDefFoundError: org/apache/commons/compress/archivers/zip/ZipFile ...
- Linux世界的三种压缩解压方式,zip/unzip方式压缩解压、tar方式压缩解压、jar方式压缩解压暨shopt extglob反选示例
Linux世界的三种压缩解压方式,zip/unzip方式压缩解压.tar方式压缩解压.jar方式压缩解压暨shopt extglob反选示例 zip/unzip方式.tar方式压缩解压是Linux中的 ...
- java关键字 valotile_Java内存模型-jsr133规范介绍,java中volatile关键字的含义
最近在看<深入理解Java虚拟机:JVM高级特性与最佳实践>讲到了线程相关的细节知识,里面讲述了关于java内存模型,也就是jsr 133定义的规范. 系统的看了jsr 133规范的前面几 ...
- zip包怎么解压oracle,使用jar与zip压缩解压文件的区别
使用jar命令压缩和解压文件不会继承原来的权限,切记! 而使用zip/unzip压缩解压文件则会保留文件原来的权限等信息,因此使用压缩解压的时候尽量使用专业的工具 下面是测试内容和结果: 1.首先确认 ...
- 解压命令linux tgz,linux常用压缩解压命令:tar,tgz,gzip,zip,rar
一,tar (一) tar压缩命令tar -cvf examples.tar files|dir #说明: -c, --create create a new archive 创建一个归档文件 -v ...
- kafka java代码横杠_Apache Beam Kafkaio获取java.lang.illegalargumentException:无法序列化KafkaunBoundedSource...
我正在建造一条从卡夫卡读取的阿帕奇光束管道 KafkaIO 但我不知道如何解决序列化问题. 如何使用Kafkaio: this.pipeline .apply("ReadFromKafka& ...
- java中commons-net包_Apache commons net 包介绍和简单使用详解
Apache commons net 项目中封装了各种网络协议的客户端,支持的协议包括: · FTP · NNTP · SMTP · POP3 ...
- java length()函数_小猿圈介绍java函数式编码结构及优势
对于java大家都已经不陌生了吧,今天小猿圈Java讲师就分享一篇关于java函数式编码结构及优势的知识点,希望对于学习java的你有一定的帮助,想学习就需要积累. 探讨三种下一代JVM语言:Groo ...
最新文章
- php getconfig,PHP: tidy::getConfig - Manual
- flutter系列InheritedWidget介绍
- Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集
- excel用警员姓名查找警号信息
- Xception: DeepLearning with Depthwise Separable Convolutions2017Google【论文理解】
- 计算机二级(C语言)备考
- pom文件无法加载ojdbc14-10.2.0.4.0.jar
- 如何批量修改图片尺寸而不变形?
- 树莓派使用433Mhz射频无线收发
- 有关XLS文件的读取
- 基于Java的亚马逊“手机”评论爬虫的情感分类分析
- 想学.Net,只要功夫深,铁柱磨成针
- 有一位后代曾忏悔:他的祖父继承家里的淫业,到了他父亲那一代,果报现前
- 【Unity】新手初学Animation实现人物移动
- 阿里云服务器优惠以及采购流程
- 硬盘的文件格式变为RAW格式
- u盘中的android文件夹图标不显示,U盘中文件夹怎么设置自定义图标而不变样
- Web前端之jQuery库
- 一位IT新人对工作计划的心得体会
- UE4 动画重定向之使用同一套骨骼