Apache Commons Compress

简介

Apache Commons Copress是 Apache Commons系列工具的一个部分
是一个提供了更丰富的压缩功能和支持更多压缩格式的工具包

前面我们可知 Java自带对zip,gzip,jar格式的压缩文件支持
如果我们要处理7z,tar,bzip等格式
或者使用LZ4,Snappy等其他压缩算法
就可以使用 Apache Compress
因为rar压缩算法不公开 所以Apache Compress未提供支持

使用

压缩流工厂

压缩流工厂是最基础的压缩流创建工具 用于创建一个输入/输出流进行压缩/解压缩

  • 创建一个压缩输出流
    第一参数是CompressorStreamFactory.GZIP 所以是GZIP压缩流
    如果指定为其他格式 则为其他格式压缩流
CompressorOutputStream gzippedOut = new CompressorStreamFactory().createCompressorOutputStream(CompressorStreamFactory.GZIP, myOutputStream);
  • 创建一个解压缩输入流
CompressorInputStream input = new CompressorStreamFactory().createCompressorInputStream(originalInput);
  • 创建一个文档输入流
ArchiveInputStream input = new ArchiveStreamFactory().createArchiveInputStream(originalInput);

文档输入流ArchiveInputStream和解压缩输入流 CompressorInputStream的区别是
ArchiveInputStream是文档输入流 用于处理归档格式文件 用于处理ZIP,JAR,AR,CPIO,ARJ,7Z,TAR
等归档型包文件
CompressorInputStream是解压缩输入流 用于处理BZIP2,GZIP,PACK200,SNAPPY_FRAMED,
Z,DEFLATE,XZ,LZMA,LZ4_FRAMED,ZSTANDARD压缩型包文件

处理文件 格式
ArchiveInputStream 归档型包 ZIP,JAR,AR,CPIO,ARJ,7Z,TAR……
CompressorInputStream 压缩型包 BZIP2,GZIP,PACK200,SNAPPY_FRAMED……

解压缩文件 通用流程

  • 核心就是ArchiveInputStream
 ArchiveInputStream input = new ArchiveStreamFactory().createArchiveInputStream(new BufferedInputStream(new FileInputStream("F:/zipoutput.zip")));
构建的ArchiveInputStream 必须使用支持mark标记的流作为底层流 否则会抛出不支持标记异常
所以这里使用了BufferedInputStream 包装FileInputStreamFile targetDir = new File("F:\\uncompress");此处使用了try with resource(Java 7特性) 可以自动关闭流try (ArchiveInputStream i = input) {ArchiveEntry entry = null;while ((entry = i.getNextEntry()) != null) {if (!i.canReadEntryData(entry)) {不能读取 或不支持的格式 算法 跳过此文件continue;} 文件名 用于下面文件File类型的参数 所以需要设定全路径 此处为F:\uncompress\+文件名String name = targetDir + File.separator + entry.getName();File f = new File(name);if (entry.isDirectory()) {if (!f.isDirectory() && !f.mkdirs()) {throw new IOException("failed to create directory " + f);}} else {File parent = f.getParentFile();if (!parent.isDirectory() && !parent.mkdirs()) {throw new IOException("failed to create directory " + parent);}输出到目标文件 此处调用的是Java NIO的Files工具类的ewOutputStream方法try (OutputStream o = Files.newOutputStream(f.toPath())) {IOUtils.copy(i, o);}}}}
  • 从一个压缩型文件包解压
// 此处使用了NIO的文件输入流创建方式 因为NIO流是不支持标记和重置的
所以又使用了BufferedInputStream包装文件输入流
输入的文件格式是已知的tar.gz型 所以直接指定GzipCompressorInputStream为处理流
gzip处理流上又套接一层TarArchiveInputStream处理解压后的tar归档包文件
try (InputStream fi = new Files.newInputStream(Paths.get("my.tar.gz"));InputStream bi = new BufferedInputStream(fi);InputStream gzi = new GzipCompressorInputStream(bi);ArchiveInputStream o = new TarArchiveInputStream(gzi)) {
}

打包文件 通用流程

  • 核心是ArchiveOutputStream 类似JDK中提供的ZipOutputStream
    与归档文件输入流不同 ArchiveOutputStream不支持7z压缩格式,此工具提供了SevenZOutputFile类专用于处理7z格式文件压缩
需要打包的文件
Collection<File> filesToArchive = Arrays.asList(new File("E:\\图片\\截图").listFiles());createArchiveOutputStream()方法的第一个形参指定压缩文件格式 此处设定为tar格式
ArchiveOutputStream outputStream=new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.TAR,new FileOutputStream("F:\\zipArchiveoutput.tar"));
try (ArchiveOutputStream o = outputStream) {for (File f : filesToArchive) {ArchiveEntry entry = o.createArchiveEntry(f, f.getName());o.putArchiveEntry(entry);if (f.isFile()) {try (InputStream i = Files.newInputStream(f.toPath())) {使用IOUtils工具方法进行写入IOUtils.copy(i, o);}}每写入完一个实体 必须关闭这个实体 o.closeArchiveEntry();}压缩完毕此处和JDK的ZipOutputStream的finsh()方法不一样 ZipOutputStream是自动关闭所有未关闭实体的而Apache compress必须手动关闭实体outputStream.finish();
}

7z文件

压缩和解压缩7z文件 必须要手动添加依赖 ## XZ For Java
Apache compress反正是没有引用这个依赖包
官方文档只提示了使用一些特殊算法是需要引入此依赖
但实际上压缩7z文件必须引入依赖 如果不手动引入就会抛出未找到类异常

Gradle引入

compile group: 'org.tukaani', name: 'xz', version: '1.8'
  • 打包7z文件
    代码上大同小异
   Collection<File> filesTo7z = Arrays.asList(new File("E:\\图片\\B站截图").listFiles());try (SevenZOutputFile sevenZOutputFile = new SevenZOutputFile(new File("F:\\7zoutput."+ArchiveStreamFactory.SEVEN_Z))) {设置压缩算法 默认是LZMA2 通常用默认的即可sevenZOutputFile.setContentCompression(SevenZMethod.LZMA2);for (File file : filesTo7z) {创建压缩实体SevenZArchiveEntry entry = sevenZOutputFile.createArchiveEntry(file, file.getName());放入压缩文件 和其他几种压缩流基本一致的操作sevenZOutputFile.putArchiveEntry(entry);try (FileInputStream fis = new FileInputStream(file)) {byte[] bytes=new byte[4096];int len=-1;while ((len = fis.read(bytes)) != -1) {sevenZOutputFile.write(bytes,0,len);}}sevenZOutputFile.closeArchiveEntry();}}
  • 解压缩7z文件
    从文件解压
        SevenZFile sevenZFile = new SevenZFile(new File("F:\\7zoutput.7z"));for (SevenZArchiveEntry entry : sevenZFile.getEntries()) {try (FileOutputStream fous = new FileOutputStream("F:\\uncompress\\" + entry.getName())) {每次要读入文件时 必须调用getNextEntry()方法 此时才会真正的打开输入流 否则会直接抛出越界异常sevenZFile.getNextEntry();byte[] content = new byte[4096];int len=-1;while ((len = sevenZFile.read(content)) != -1) {fous.write(content,0,len);}}}sevenZFile.close();

从内存解压

       byte[] inputData=new byte[]{}; 文件在内存中的数据输入NIO的内存通道SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(inputData);构造SevenZFile SevenZFile sevenZFile = new SevenZFile(inMemoryByteChannel);SevenZArchiveEntry entry = sevenZFile.getNextEntry();读取sevenZFile.read(); 

解压7加密文件

此构造方法的第二个参数为加密密码 此处输入密码为“secret”
SevenZFile sevenZFile = new SevenZFile(new File("archive.7z"), "secret"..toCharArray());
解压过程和未加密文件无区别
for (SevenZArchiveEntry entry : sevenZFile.getEntries()) {try (FileOutputStream fous = new FileOutputStream("F:\\uncompress\\" + entry.getName())) {每次要读入文件时 必须调用getNextEntry()方法 此时才会真正的打开输入流 否则会直接抛出越界异常sevenZFile.getNextEntry();byte[] content = new byte[4096];int len=-1;while ((len = sevenZFile.read(content)) != -1) {fous.write(content,0,len);}}}

LZ4压缩

LZ4是压缩速度和压缩效率都比较高的一种压缩文件算法

  • 压缩
InputStream in = Files.newInputStream(Paths.get("F:\\zipArchiveoutput.tar"));
OutputStream fout = Files.newOutputStream(Paths.get("F:\\zipArchiveoutput.tar.lz4"));
BufferedOutputStream out = new BufferedOutputStream(fout);
FramedLZ4CompressorOutputStream lzOut = new FramedLZ4CompressorOutputStream(out);
IOUtils.copy(in,lzOut);
lzOut.close();
in.close();
  • 解压缩
InputStream fin = Files.newInputStream(Paths.get("F:\\zipArchiveoutput.tar.lz4"));
BufferedInputStream in = new BufferedInputStream(fin);
OutputStream out = Files.newOutputStream(Paths.get("F:\\archive.tar"));
FramedLZ4CompressorInputStream zIn = new FramedLZ4CompressorInputStream(in);
IOUtils.copy(zIn,out);
out.close();
zIn.close();

[重学Java基础][Java IO流][Exter.1]Apache Commonms Compress压缩工具包相关推荐

  1. 【Java基础】· IO流习题详解

    写在前面 Hello大家好, 我是[麟-小白],一位软件工程专业的学生,喜好计算机知识.希望大家能够一起学习进步呀!本人是一名在读大学生,专业水平有限,如发现错误或不足之处,请多多指正!谢谢大家!!! ...

  2. Java基础学习—— IO流

    Java基础学习-- IO流 1 文件 1.1 文件的创建 1.2 文件常用的方法 2 IO流 2.1 FileInputStream 2.2 FileOutputStream 2.3 文件的拷贝 2 ...

  3. Java基础进阶IO流概述

    1.IO流,什么是IO? I : Input O : Output 通过IO可以完成硬盘文件的读和写. 2.IO流的分类? 有多种分类方式: 一种方式是按照流的方向进行分类: 以内存作为参照物 往内存 ...

  4. 【java基础】IO流是啥?有啥用?(上)

    今天我们说说java代码中对文件的操作,比如新建删除文件,读取文件内容等. File类 File类用于操作文件和目录,可对文件或目录进行新建,删除和重命名等操作.但是如果要访问文件内容本身,就需要用到 ...

  5. Java基础:IO 流中的 flush

    无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家.教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家.点 这里 可以跳转到教程. 内容概要 Java IO ...

  6. Java基础之IO流操作

    第14章 File类与IO流 主要内容 File类 字节流 字符流 文件流 缓冲流 转换流 数据流 对象流 打印流 Scanner与System与IO流 教学目标 使用File类对象表示文件或目录 能 ...

  7. Java基础之IO流

    IO流用来处理设备间数据传输,java对数据的操作是通过流的方式,而这些操作流的对象被封装在IO包中.流可以分为字符流和字节流.字符流可以设置编码方式,这就使得处理文本更加方便. IO常用基类 字节流 ...

  8. Java基础知识——IO流

    简介 IO是指Input/Output,即输入和输出.以内存为中心: Input指从外部读入数据到内存,例如,把文件从磁盘读取到内存,从网络读取数据到内存等等 Output指把数据从内存输出到外部,例 ...

  9. Java基础之IO流(一)

    IO流(一) IO流:输入输出的流动 IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中 流按操作数据分为两种:字节流与字符流 . 流按流向分为 ...

最新文章

  1. 让模糊图片变视频,找回丢失的时间维度,MIT这项新研究简直像魔术
  2. juggle dsl语法介绍及codegen浅析
  3. JAVA四圣降临,和平精英四圣降临模式攻略
  4. 常见的java异常——java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path...
  5. 如何在page_load方法判断是服务器端控件引发的page_load方法
  6. 安装 Oracle Database PSU 10.2.0.4.2 步骤
  7. vue.js 四(指令和自定义指令)
  8. 4列变成5列 datatable_云南美食界“5巨头”,谁才是NO.1?你家乡的那道菜也在列...
  9. mybatis配置log4j控制台打印SQL语句
  10. 分子动力学模拟的主要步骤
  11. 程序员英文简历范例(通用,含初级、中级和高级)
  12. 复合查询sql子查询操作
  13. Chrome 科研神器!去谷歌学术搜到文章,代码链接就能自动展示
  14. 《说服力》读后总结摘录
  15. ⅰsee是什么意思_see是什么意思
  16. php octet stream,为什么上传图片时,type 显示application/octet-stream 呢? 原
  17. python怎么保留整数输出_python怎么保留整数
  18. DoubanFm之设计模式(一)
  19. 高德地图功能点使用整理
  20. 你的广告语,为什么用户记不住?

热门文章

  1. MacOSX 编译Android 4.0的各种问题
  2. 计算机或与非门原理,计算机逻辑电路中,与或门,或非门,异或非门,异或门的性质,在线等!!!!...
  3. 电脑突然无法播放html音频,联想电脑突然没声音了音乐也播放不了,这到底是为什么啊...
  4. matlab绘图(1)
  5. VUE2安装初始化步骤(2022)
  6. iSubtitle for Mac(视频字幕制作软件)
  7. iphone忘记锁屏密码如何解决
  8. 机器人工程的工作与考研之困惑“以学生为中心”
  9. 快手2020春季实习生及校招补招程序B卷
  10. SpringBoot JPA(JpaRepository)动态查询 分页展示