目录

Apache Commons Compress 概述

本地文件解压缩代码示例

文件压缩并提供网络下载


Apache Commons Compress 概述

1、Apache Commons Compress 官网:http://commons.apache.org/proper/commons-compress/index.html

2、Apache Commons Compress 库定义了一个用于处理 ar,cpio,Unix 转储,tar,zip,gzip,XZ,Pack200,bzip2、7z,arj,lzma,snappy,DEFLATE,lz4,Brotli,Zstandard,DEFLATE64 和 Z 文件的 API 。

3、当前 Compress 版本是 1.19,并且需要 Java 7 及以上支持。

现在 ParallelScatterZipCreator 会按照条目添加到存档的顺序来写入条目。

现在默认情况下解析额外的字段时 ZipArchiveInputStream和ZipFile 更具宽容性。

TarArchiveInputStream 具有新的宽松模式,该模式可能允许它读取某些已损坏的档案。

4、官网用户使用手册提供了各种压缩格式的处理方式(本文仅以常用的 zip 格式为例进行介绍):http://commons.apache.org/proper/commons-compress/examples.html

5、Apache Commons Compress 官网下载:http://commons.apache.org/proper/commons-compress/download_compress.cgi

6、可以从 Maven 中央仓库获取依赖:https://mvnrepository.com/artifact/org.apache.commons/commons-compress

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.19</version>
</dependency>

核心 API

1)压缩输入流,用于解压压缩文件:public abstract class ArchiveInputStream extends java.io.InputStream

2)压缩输处出流,用于压缩压缩文件:public abstract class ArchiveOutputStream extends java.io.OutputStream

3)压缩文件内部存档的条目,压缩文件内部的每一个被压缩文件都称为一个条目:public interface ArchiveEntry

本地文件解压缩代码示例

1、生产中常见的需求之一就是对服务器上的某些文件进行压缩,或者解压。本文以常用的 zip 格式为例进行介绍。

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import java.io.*;
/*** 压缩工具类** @author helloworld*/
public class ZipUtil {/*** 将文件打包成 zip 压缩包文件** @param sourceFiles        待压缩的多个文件列表。只支持文件,不能有目录,否则抛异常。* @param zipFile            压缩文件。文件可以不存在,但是目录必须存在,否则抛异常。如 C:\Users\Think\Desktop\aa.zip* @param isDeleteSourceFile 是否删除源文件(sourceFiles)* @return 是否压缩成功*/public static boolean archiveFiles2Zip(File[] sourceFiles, File zipFile, boolean isDeleteSourceFile) {InputStream inputStream = null;//源文件输入流ZipArchiveOutputStream zipArchiveOutputStream = null;//压缩文件输出流if (sourceFiles == null || sourceFiles.length <= 0) {return false;}try {zipArchiveOutputStream = new ZipArchiveOutputStream(zipFile);//ZipArchiveOutputStream(File file) :根据文件构建压缩输出流,将源文件压缩到此文件.//setUseZip64(final Zip64Mode mode):是否使用 Zip64 扩展。// Zip64Mode 枚举有 3 个值:Always:对所有条目使用 Zip64 扩展、Never:不对任何条目使用Zip64扩展、AsNeeded:对需要的所有条目使用Zip64扩展zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);for (File file : sourceFiles) {//将每个源文件用 ZipArchiveEntry 实体封装,然后添加到压缩文件中. 这样将来解压后里面的文件名称还是保持一致.ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(file.getName());zipArchiveOutputStream.putArchiveEntry(zipArchiveEntry);inputStream = new FileInputStream(file);//获取源文件输入流byte[] buffer = new byte[1024 * 5];int length = -1;//每次读取的字节大小。while ((length = inputStream.read(buffer)) != -1) {//把缓冲区的字节写入到 ZipArchiveEntryzipArchiveOutputStream.write(buffer, 0, length);}}zipArchiveOutputStream.closeArchiveEntry();//写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常zipArchiveOutputStream.finish();//压缩结束.if (isDeleteSourceFile) {//为 true 则删除源文件.for (File file : sourceFiles) {file.deleteOnExit();}}} catch (IOException e) {e.printStackTrace();return false;} finally {//关闭输入、输出流,释放资源.try {if (null != inputStream) {inputStream.close();}if (null != zipArchiveOutputStream) {zipArchiveOutputStream.close();}} catch (IOException e) {e.printStackTrace();}}return true;}/*** 将 zip 压缩包解压成文件到指定文件夹下** @param zipFile   待解压的压缩文件。亲测  .zip 文件有效;.7z 压缩解压时抛异常。* @param targetDir 解压后文件存放的目的地. 此目录必须存在,否则异常。* @return 是否成功*/public static boolean decompressZip2Files(File zipFile, File targetDir) {InputStream inputStream = null;//源文件输入流,用于构建 ZipArchiveInputStreamOutputStream outputStream = null;//解压缩的文件输出流ZipArchiveInputStream zipArchiveInputStream = null;//zip 文件输入流ArchiveEntry archiveEntry = null;//压缩文件实体.try {inputStream = new FileInputStream(zipFile);//创建输入流,然后转压缩文件输入流zipArchiveInputStream = new ZipArchiveInputStream(inputStream, "UTF-8");//遍历解压每一个文件.while (null != (archiveEntry = zipArchiveInputStream.getNextEntry())) {String archiveEntryFileName = archiveEntry.getName();//获取文件名File entryFile = new File(targetDir, archiveEntryFileName);//把解压出来的文件写到指定路径byte[] buffer = new byte[1024 * 5];outputStream = new FileOutputStream(entryFile);int length = -1;while ((length = zipArchiveInputStream.read(buffer)) != -1) {outputStream.write(buffer, 0, length);}outputStream.flush();}} catch (IOException e) {e.printStackTrace();return false;} finally {try {if (null != outputStream) {outputStream.close();}if (null != zipArchiveInputStream) {zipArchiveInputStream.close();}if (null != inputStream) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}}return true;}
}

文件压缩并提供网络下载

1、生产中另一个常见的需求是,用户下载的时候,有时候需要将多个文件打包成一个文件后提供下载。

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;/*** 压缩文件下载工具类。用于将多文件文件压缩后,提供给 ServletOutputStream 输出流共用户网页下载*/
@SuppressWarnings("all")
public class ZipFileDownloadUtils {/*** 压缩本地多个文件并提供输出流下载** @param filePaths   :本地文件路径,如 ["C:\\wmx\\temp\\data1.json","C:\\wmx\\temp\\data2.json"]。只支持文件,不能有目录,否则抛异常。* @param zipFileName :压缩文件输出的名称,如 "年终总结" 不含扩展名。默认文件当前时间。如 20200108111213.zip* @param response    :提供输出流*/public static void zipFileDownloadByFile(Set<String> filePaths, String zipFileName, HttpServletResponse response) {try {//1)参数校验if (filePaths == null || filePaths.size() <= 0) {throw new RuntimeException("待压缩导出文件为空.");}if (zipFileName == null || "".equals(zipFileName)) {zipFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".zip";} else {zipFileName = zipFileName + ".zip";}//2)设置 response 参数。这里文件名如果是中文,则导出乱码,可以response.reset();response.setContentType("content-type:octet-stream;charset=UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName, "utf-8"));//3)通过 OutputStream 创建 zip 压缩流。如果是压缩到本地,也可以直接使用 ZipArchiveOutputStream(final File file)ServletOutputStream servletOutputStream = response.getOutputStream();ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(servletOutputStream);//4)setUseZip64(final Zip64Mode mode):是否使用 Zip64 扩展。// Zip64Mode 枚举有 3 个值:Always:对所有条目使用 Zip64 扩展、Never:不对任何条目使用Zip64扩展、AsNeeded:对需要的所有条目使用Zip64扩展zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);for (String filePath : filePaths) {File file = new File(filePath);String fileName = file.getName();InputStream inputStream = new FileInputStream(file);//5)使用 ByteArrayOutputStream 读取文件字节ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int readLength = -1;while ((readLength = inputStream.read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, readLength);}if (byteArrayOutputStream != null) {byteArrayOutputStream.flush();}byte[] fileBytes = byteArrayOutputStream.toByteArray();//整个文件字节数据//6)用指定的名称创建一个新的 zip 条目(zip压缩实体),然后设置到 zip 压缩输出流中进行写入.ArchiveEntry entry = new ZipArchiveEntry(fileName);zipArchiveOutputStream.putArchiveEntry(entry);//6.1、write(byte b[]):从指定的字节数组写入 b.length 个字节到此输出流zipArchiveOutputStream.write(fileBytes);//6.2、写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常zipArchiveOutputStream.closeArchiveEntry();if (byteArrayOutputStream != null) {byteArrayOutputStream.close();}}//7)最后关闭 zip 压缩输出流.if (zipArchiveOutputStream != null) {zipArchiveOutputStream.close();}} catch (IOException e) {e.printStackTrace();}}/*** 压缩本地多个文件并提供输出流下载。只支持文件,不能有目录,否则抛异常。** @param fileLists   :本地文件,如 ["C:\\wmx\\temp\\data1.json","C:\\wmx\\temp\\data2.json"]。* @param zipFileName :压缩文件输出的名称,如 "年终总结" 不含扩展名。默认文件当前时间。如 20200108111213.zip* @param response    :提供输出流*/public static void zipFileDownloadByFile(List<File> fileLists, String zipFileName, HttpServletResponse response) {if (fileLists == null || fileLists.size() <= 0) {throw new RuntimeException("待压缩导出文件为空.");}Set<String> filePaths = new HashSet<>();for (File file : fileLists) {filePaths.add(file.getAbsolutePath());}zipFileDownloadByFile(filePaths, zipFileName, response);}/*** 压缩网络文件。** @param urlLists,待压缩的网络文件地址,如 ["http://www.baidu.com/img/bd_logo1.png"]* @param zipFileName* @param response*/public static void zipFileDownloadByUrl(List<URL> urlLists, String zipFileName, HttpServletResponse response) {try {//1)参数校验if (urlLists == null || urlLists.size() <= 0) {throw new RuntimeException("待压缩导出文件为空.");}if (zipFileName == null || "".equals(zipFileName)) {zipFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".zip";} else {zipFileName = zipFileName + ".zip";}//2)设置 response 参数response.reset();response.setContentType("content-type:octet-stream;charset=UTF-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName, "utf-8"));//3)通过 OutputStream 创建 zip 压缩流。如果是压缩到本地,也可以直接使用 ZipArchiveOutputStream(final File file)ServletOutputStream servletOutputStream = response.getOutputStream();ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(servletOutputStream);//4)setUseZip64(final Zip64Mode mode):是否使用 Zip64 扩展。// Zip64Mode 枚举有 3 个值:Always:对所有条目使用 Zip64 扩展、Never:不对任何条目使用Zip64扩展、AsNeeded:对需要的所有条目使用Zip64扩展zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);for (URL url : urlLists) {String fileName = getNameByUrl(url);InputStream inputStream = url.openStream();//5)使用 ByteArrayOutputStream 读取文件字节ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int readLength = -1;while ((readLength = inputStream.read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, readLength);}if (byteArrayOutputStream != null) {byteArrayOutputStream.flush();}byte[] fileBytes = byteArrayOutputStream.toByteArray();//整个文件字节数据//6)用指定的名称创建一个新的 zip 条目(zip压缩实体),然后设置到 zip 压缩输出流中进行写入.ArchiveEntry entry = new ZipArchiveEntry(fileName);zipArchiveOutputStream.putArchiveEntry(entry);//6.1、write(byte b[]):从指定的字节数组写入 b.length 个字节到此输出流zipArchiveOutputStream.write(fileBytes);//6.2、写入此条目的所有必要数据。如果条目未压缩或压缩后的大小超过4 GB 则抛出异常zipArchiveOutputStream.closeArchiveEntry();if (byteArrayOutputStream != null) {byteArrayOutputStream.close();}}//7)最后关闭 zip 压缩输出流.if (zipArchiveOutputStream != null) {zipArchiveOutputStream.close();}} catch (IOException e) {e.printStackTrace();}}/*** 压缩网络文件** @param urlPaths    待压缩的网络文件地址,如 ["http://www.baidu.com/img/bd_logo1.png"]* @param zipFileName* @param response*/public static void zipFileDownloadByUrl(Set<String> urlPaths, String zipFileName, HttpServletResponse response) {if (urlPaths == null || urlPaths.size() <= 0) {throw new RuntimeException("待压缩导出文件为空.");}List<URL> urlList = new ArrayList<>();for (String urlPath : urlPaths) {try {urlList.add(new URL(urlPath));} catch (MalformedURLException e) {e.printStackTrace();}}zipFileDownloadByUrl(urlList, zipFileName, response);}/*** 通过 url 获取文件的名称** @param url,如 http://www.baidu.com/img/bd_logo1.png* @return*/private static String getNameByUrl(URL url) {String name = url.toString();int lastIndexOf1 = name.lastIndexOf("/");int lastIndexOf2 = name.lastIndexOf("\\");if (lastIndexOf1 > 0) {name = name.substring(lastIndexOf1 + 1, name.length());} else if (lastIndexOf2 > 0) {name = name.substring(lastIndexOf1 + 2, name.length());}return name;}
}

Apache Commons Compress 文件解压缩库相关推荐

  1. Apache Commons Compress

    Apache Commons是Apache软件基金会的项目,曾隶属于Jakarta项目.Commons的目的是提供可重用的.开源的Java代码.Apache Commons包含了很多开源的工具,用于解 ...

  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. java apache commons_使用java apache commons下载文件?

    如果您正在寻找一种获取下载前总字节数的方法,您可以从http响应中的Content-Length头部获取此值. 如果您只想在下载后的最终字节数,最简单的方法是检查您要写入的文件大小. 但是,如果要显示 ...

  4. Apache工具库——Apache Commons的使用

    Apache Commons是Apache开源的一个java组件库,其中包含了大量子项目,其中常用的组件有: 组件 功能介绍 BeanUtils 提供了对于JavaBean进行各种操作,克隆对象,属性 ...

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

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

  6. c++解析csv 存入数组_使用Apache Commons CSV在Java中读写CSV

    介绍 这是专门针对Java读写CSV的库的简短系列文章的第二篇,也是上一篇文章" Core Java读写CSV"的直接续篇. Apache Commons CSV 在Apache的 ...

  7. 常用Apache Commons工具类备忘

    常用Apache Commons工具类 ----------------------------------------------------------------- 例如:commons.lan ...

  8. commons compress使用+ziji

    此文介绍apache的压缩包,好处是可以自己设置ZipFile文件名的编码. 而jdk自带的ZipFIle只支持utf-8,导致压缩后中文出现乱码. *下面给出个zip压缩解压的示例 ---zip压缩 ...

  9. java 7zip解压_Apache Commons Compress介绍-JAVA压缩解压7z文件

    7zip(下面简称7z)是由Igor Pavlov所开发的一种压缩格式,主要使用的压缩算法是LZMA/LZMA2.7z是一种压缩比非常高的格式,这与其压缩算法LZMA有直接关系,所以很多大文件都是用7 ...

  10. android.net是哪个jar,【Android Clock Synchronization】Android时钟同步:基于NTP协议的第三方库Apache Commons Net......

    Apache Commons Net Apache Commons Net库实现了许多基本的客户端网络协议,其中包括NTP/SNTP. 1.创建JAR包 进入下载页,当前的最新版本是Commons N ...

最新文章

  1. Vyond制作2D动画学习教程
  2. 工业界如何解决NER问题?12个trick,与你分享~
  3. discuz手机版模板开发
  4. linux 源码安装 yum rpm区别
  5. php函数剩余时间,php计算剩余时间的自定义函数
  6. codevs 2865 天平系统1
  7. 【python】解决[SSL: CERTIFICATE_VERIFY_FAILED]
  8. 华为mate50麒麟处理器鸿蒙系统,华为Mate50Pro:有鸿蒙OS,处理器你选择麒麟还是高通...
  9. 了解SQL Server触发器及触发器中的事务
  10. 世界第一位计算机程序员竟是女的!拜伦之女传奇一生
  11. redis 介绍和常用命令
  12. 标准C程序设计七---120
  13. 抢购 mysql 优化_处理抢购、秒杀应用场景降低“超卖”发生几个优化方案(php)...
  14. ios判断当前设备类型
  15. mswinsck.ocx 一个文件丢失或无效_AutoCAD文件修复的10种方法
  16. java复制文件乱码_为什么用JAVA写的一个复制文本文档的程序复制出来文本文档乱码...
  17. ionic2中的订单详情页面
  18. Google reCaptcha验证码无法显示解决方案
  19. 评价的等级优良差_小学生期末评语-等级优良合格(最佳版本)
  20. 23.卷积神经网络实战-ResNet

热门文章

  1. Object中Equals和ReferenceEquals不解之谜
  2. 如何有效创建工作分解结构?
  3. 处理顶点——使用顶点缓冲和索引缓冲将顶点和索引保存在显存中
  4. line search中的重要定理 - 梯度与方向的点积为零
  5. 漫谈 Clustering (番外篇): Expectation Maximization
  6. Bresenham画线算法详解及其OpenGL编程实现
  7. 拓端tecdat|R语言结合新冠疫情COVID-19对股票价格预测:ARIMA,KNN和神经网络时间序列分析
  8. 拓端tecdat|R语言使用Rasch模型分析学生答题能力
  9. 拓端tecdat|R语言随机搜索变量选择SSVS估计贝叶斯向量自回归(BVAR)模型
  10. 拓端tecdat|python安娜卡列妮娜词云图制作