iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > JAVA >Java压缩与解压缩ZIP文件
  • 487
分享到

Java压缩与解压缩ZIP文件

javazip压缩文件解压缩文件ZipOutputStream 2023-09-11 19:09:07 487人浏览 独家记忆
摘要

文章目录 前言Java解压缩文件压缩和解压缩ZIP文件检验应用总结 前言 在现代计算机上,数据传输和存储越来越依赖于文件压缩技术。当我们需要发送大量数据时,压缩文件可以大大减少传输时间

文章目录

前言

在现代计算机上,数据传输和存储越来越依赖于文件压缩技术。当我们需要发送大量数据时,压缩文件可以大大减少传输时间和网络带宽,而且压缩文件还可以帮助我们节省磁盘空间。在Java中提供了压缩和解压缩文件的功能,可以使用java.util.zip包中的类来实现。本篇将对如何使用 Java 实现单文多件压缩和解压缩进行总结

文件压缩指的是将一个或多个文件通过压缩算法,将其存储为一个更小的文件,以便于存储和传输。压缩的原理是通过对文件的数据进行编码和压缩,使其占用更少的空间。压缩后的文件可以通过解压缩算法还原成原始的文件格式。在文件压缩过程中,常见的操作是将多个文件打包成一个压缩文件,例如zip、tar等格式。

Java解压缩文件

常见的文件压缩格式包括:

  • ZIP:最常见的压缩文件格式之一,可以存储一个或多个文件,并可在不同的操作系统中进行解压缩。
  • TAR:linux系统中的常见文件压缩格式,通常用于打包多个文件,但不会进行压缩。
  • GZIP:常用的文件压缩格式,通常用于压缩单个文件,可以获得更高的压缩比。
  • BZIP2:高效的压缩算法,通常用于压缩文本文件和XML文件等。
  • jar: Jar包对于Java开发同学来说肯定很熟悉,其也是一个压缩包

Java提供了多种用于压缩和解压缩文件的api,主要包括以下类和方法:

  • ZipOutputStream 和 ZipInputStream:用于创建和读取ZIP格式的压缩文件。
  • GZIPOutputStream 和 GZIPInputStream:用于创建和读取GZIP格式的压缩文件。
  • JarOutputStream 和 JarInputStream:用于创建和读取JAR格式的压缩文件。
  • DeflaterOutputStream 和 InflaterInputStream:用于创建和读取DEFLATE格式的压缩文件。
  • CheckedOutputStream 和 CheckedInputStream:用于在压缩和解压缩过程中计算文件的校验和。

压缩和解压缩ZIP文件

通过使用Java 自带的 java.util.zip 类库下的ZipOutputStreamZipInputStreamZipEntry实现文件的压缩和解压缩,其中ZipOutputStream用于创建ZIP压缩文件输出流输出ZIP压缩文件,ZipInputStream用于创建ZIP文件输入流读取ZIP文件用于解压缩而ZipEntry对应ZIP压缩包中的每个被压缩对象;

  • 生成ZIP文件

    压缩单个文件或者单个文件夹方法,代码如下:

    public static void zipCompress(File sourceFile, File zipFile) {    try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) {        // 设置压缩方法        zos.setMethod(ZipOutputStream.DEFLATED);        zos.setLevel(Deflater.BEST_COMPRESSioN); // 默认为-1,压缩级别,1速度快,效率低,9 速度满,效率高        // zos.setLevel(Deflater.BEST_SPEED);        zos.setComment("zip文件说明");        // 处理文件夹        if (sourceFile.exists() && sourceFile.isDirectory() && Objects.nonNull(sourceFile.listFiles())){            Arrays.stream(Objects.requireNonNull(sourceFile.listFiles())).forEach(file -> {                addZipFile(file, zos);            });        }else{            addZipFile(sourceFile, zos);        }    } catch (IOException e) {        e.printStackTrace();    }}

    为了支持读取单个文件夹进行压缩,增加一个向ZipOutputStream中添加ZipEntry的方法,代码如下:

    private static void addZipFile(File file, ZipOutputStream zos){    if (!file.exists() || file.isDirectory()){        throw new RuntimeException("文件不存在或该文件为文件夹,请检查");    }    try {        // 读入文件        FileInputStream fis = new FileInputStream(file);        // 创建压缩对象并设置一些属性        ZipEntry entry = new ZipEntry(file.getName());        entry.setMethod(ZipEntry.DEFLATED); // 压缩方法默认为DEFLATED        // entry.setMethod(ZipEntry.STORED); // STORED(不压缩)。当使用STORED压缩方法时,需要设置未压缩的数据大小和CRC-32校验和,否则压缩和解压缩时会出现错误。        entry.setSize(file.length()); // 设置未压缩的数据大小,这里设置的是文件大小        // 计算 CRC-32 校验码        // byte[] data = Files.readAllBytes(file.toPath());        // CRC32 crc = new CRC32();        // crc.update(data);        // entry.setCrc(crc.getValue()); // 设置CRC-32校验和,用于保证压缩后的数据完整性,尽量别手动设置,可以通过CRC-32计算        entry.setCompressedSize(file.length()); // 设置压缩后的数据大小,这里设置的是使用DEFLATED方法压缩后的数据大小        entry.setExtra(new byte[]{}); // 设置额外的数据,这里设置为空        entry.setComment("file comment"); // 设置ZipEntry的注释,即文件说明        entry.setCreationTime(FileTime.from(Instant.now())); // 设置文件的创建时间        entry.setLastAccessTime(FileTime.from(Instant.now())); // 设置文件的最后访问时间        entry.setLastModifiedTime(FileTime.from(Instant.now())); // 设置文件的最后修改时间。        // 向ZIP输出流中添加一个ZIP实体,构造方法中的name参数指定文件在ZIP包中的文件名        zos.putNextEntry(entry);        // 向ZIP实体中写入内容        byte[] buf = new byte[1024];        int len;        while ((len = fis.read(buf)) > 0) {            zos.write(buf, 0, len);        }        // 关闭ZipEntry        zos.closeEntry();    } catch (IOException e) {        e.printStackTrace();    }}

    注意:

    涉及到文件IO流,如果没有使用try with source 的语法,一定要记得关闭输入输出流;

    使用Java.util.zip下的工具类压缩成ZIP不支持设置ZIP密码且每种模式下生成的ZIP文件大小大于等于原文件/文件夹;

    当使用STORED压缩方法时,需要设置未压缩的数据大小和CRC-32校验和,该值需要借助CRC-32计算非常的麻烦,不设置此值会抛出异常;

    对于压缩,可以使用 ZipOutputStream 的 putNextEntry 方法逐个添加文件,避免将所有文件一次性读入内存;

    可以设置缓冲区大小,例如对于文件的读取和写入,可以设置缓冲区大小为 4KB 或者 8KB,减少内存的占用;

    对于解压缩,可以使用 ZipInputStream 的 getNextEntry 方法逐个读取文件,避免将所有文件一次性读入内存;

  • 解压缩ZIP文件

    将ZIP文件解压缩支持生成文件夹,代码如下:

    public static void zipDecompress(File zipFile, File destDir) {    byte[] buffer = new byte[1024];    try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile))) {        ZipEntry entry = zis.getNextEntry();        while (entry != null) {            File file = new File(destDir, entry.getName());            if (entry.isDirectory()) {                file.mkdirs();            } else {                File parent = file.getParentFile();                if (!parent.exists()) {                    parent.mkdirs();                }                try (FileOutputStream fos = new FileOutputStream(file)) {                    int len;                    while ((len = zis.read(buffer)) > 0) {                        fos.write(buffer, 0, len);                    }                }            }            entry = zis.getNextEntry();        }    } catch (IOException e) {        e.printStackTrace();    }}
  • 如何避免压缩文件中的注入攻击?

    压缩文件中的路径名和文件名可以被精心构造的攻击者利用,从而使得解压缩的过程中可能会导致路径遍历、文件覆盖等问题,进而导致安全问题。为了避免这些安全问题,可以进行如下处理:

    • 限制压缩文件中的路径名和文件名的长度,以及字符集,可以采用白名单机制对输入进行限制;
    • 对于解压缩的路径名和文件名,不要使用压缩文件中的路径名和文件名,而是在解压缩时自行构造一个路径名和文件名;
    • 对于不可信任的压缩文件,最好在安全的环境下解压缩,例如在沙箱或虚拟机中进行操作。

检验

主要测试使用上述代码压缩单文件和解压缩单文件能否成功以后测量单个文件的处理耗时,同时测试单文件夹多文件压缩和解压缩能否成功以及处理耗时,单元测试代码如下:

@Testvoid testJavaUtilZip(){    // 测试压缩和解压缩单文件ZIP    // 被压缩的MP4单文件,大小112.5MB    File inputFile = new File("/Users/zlc/Documents/own/images/GPT-4 Developer Livestream.mp4");    // ZIP文件路径    File zipFile = new File("/Users/zlc/Documents/own/mp4.zip");    // ZIP 解压缩路径    File unzipFile = new File("/Users/zlc/Documents/own/unzip");    long start = System.currentTimeMillis();    // 压缩文件    ZipFileUtil.zipCompress(inputFile, zipFile);    long end = System.currentTimeMillis();    System.out.println("ZIP-压缩单文件耗时:" + (end - start) + "毫秒");    start = System.currentTimeMillis();    ZipFileUtil.zipDecompress(zipFile, unzipFile);    end = System.currentTimeMillis();    System.out.println("ZIP-解压缩单文件耗时:" + (end - start) + "毫秒");    // 单文件夹多文件压缩和解压缩测试    // 文件夹大小2.42G    File inputFiles = new File("/Users/zlc/Documents/own/images");    File zipFiles = new File("/Users/zlc/Documents/own/imagesZip.zip");    File unzipFiles = new File("/Users/zlc/Documents/own/imagesUnzip");    start = System.currentTimeMillis();    // 压缩文件    ZipFileUtil.zipCompress(inputFiles, zipFiles);    end = System.currentTimeMillis();    System.out.println("ZIP - 多文件压缩耗时:" + (end - start) + "毫秒");    start = System.currentTimeMillis();    ZipFileUtil.zipDecompress(zipFiles, unzipFiles);    end = System.currentTimeMillis();    System.out.println("ZIP - 多文件解压缩耗时:" + (end - start) + "毫秒");}

测试结果如下:

ZIP-压缩单文件耗时:5492毫秒ZIP-解压缩单文件耗时:1920毫秒ZIP - 多文件压缩耗时:136059毫秒ZIP - 多文件解压缩耗时:45739毫秒

同时测试了设置不同压缩等级的耗时比较,结果如下:

// 不同压缩等级下的处理耗时 BEST_COMPRESSION 2.43G 文件夹耗时119801毫秒快两分钟了BEST_SPEED 2.43G 文件夹耗时112646毫秒 也没差多少,但确实快了

结论:

测试环境为MacOS 四核Intel Core i7,16G内存,处理将近2.5G大小的文件夹耗时接近两分钟,效率十分低下,在总文件大小不大的时候可以考虑使用jdk自带的压缩工具类。

应用

设计一个API,通过使用Hutool生成两个CSV文件和一个excel文件,将这三个文件放入到ZIP压缩包中,当通过浏览器调用API时,下载ZIP压缩包。

同时在服务器上不生成CVS、EXCEL以及Zip文件而是直接通过httpservletResponse将文件传送给客户端,避免服务器因过多生成这些文件导致服务硬盘不够用(PS:生成文件以后基本上不会有人管了,会随着时间的增加爆炸式增加,当然如果你需要留存建议生成本地文件存储到OSS中),代码如下:

  @GetMapping(value = "/downloadZip")public String downloadZipFile(HttpServletResponse response) {    // 设置响应头    response.setContentType("application/octet-stream");    response.setHeader("Content-Disposition", "attachment; filename=download.zip");    try (ZipOutputStream outputStream = new ZipOutputStream(response.getOutputStream())) {        ExcelWriter writer = new ExcelWriter(true);        List<String> header = Arrays.asList("开始日期", "结束日期", "算法厂商", "期末资产总额", "累计成交金额",                "期间委托笔数", "期间成交笔数", "期间撤单笔数");        writer.writeHeadRow(header);        List<List<String>> rows = new ArrayList<>();        rows.add(Arrays.asList("张三", "里斯", "男", "张三", "里斯", "男", "张三", "里斯"));        rows.add(Arrays.asList("李四", "王武", "女", "张三", "里斯", "男", "张三", "里斯"));        writer.write(rows);        writer.passRows(1);        List<String> header1 = Arrays.asList("日期", "资金账号", "算法母单编号", "委托编号", "交易所", "股票代码",                "委托数量", "交易方向", "订单类型", "委托价格", "委托状态", "累计成交数量", "累计成交金额");        writer.writeHeadRow(header1);        writer.autoSizeColumn(writer.getCurrentRow());        List<List<String>> rows2 = new ArrayList<>();        rows2.add(Arrays.asList("张三", "里斯", "男", "张三", "里斯", "男", "张三", "里斯", "找大大", "赵打打", "炸", "茅台", "米线"));        rows2.add(Arrays.asList("李四", "王武", "女", "张三", "里斯", "男", "张三", "里斯", "找大大", "赵打打", "炸", "茅台", "米线"));        writer.write(rows2);        writer.autoSizeColumnAll();        ZipEntry entry = new ZipEntry("数据.xlsx");        outputStream.putNextEntry(entry);        writer.flush(outputStream);        writer.close();        outputStream.closeEntry();        ZipEntry entry1 = new ZipEntry("母单.csv");        outputStream.putNextEntry(entry1);        CsvWriter csvWriter1 = new CsvWriter(new OutputStreamWriter(outputStream));        String[] csvHead1 = {"日期", "资金账号", "算法厂商", "算法", "算法母单编号", "交易所", "股票代码", "委托数量", "交易方向", "启动时间", "停止时间", "算法状态"};        csvWriter1.writeLine(csvHead1);        String[] csvData1 = {"20230203", "98830901", "XX", "TWAP", "12984", "SH", "600000", "10000", "4", "102311", "112311", "1"};        String[] csvData2 = {"20230203", "98830901", "XX", "TWAP", "12984", "SH", "600000", "10000", "4", "102311", "112311", "1"};        csvWriter1.writeLine(csvData1);        csvWriter1.writeLine(csvData2);        csvWriter1.flush();        outputStream.closeEntry();        ZipEntry entry2 = new ZipEntry("子单.csv");        outputStream.putNextEntry(entry2);        CsvWriter csvWriter2 = new CsvWriter(new OutputStreamWriter(outputStream));        String[] csvHead2 = {"日期", "资金账号", "算法母单编号", "委托编号", "交易所", "股票代码", "委托数量", "交易方向", "订单类型", "委托价格", "委托状态", "累计成交数量", "累计成交金额"};        csvWriter2.writeLine(csvHead2);        String[] csvData3 = {"20230203", "98830901", "12984", "ord1122", "SH", "600000", "1000", "4", "1", "7.23", "1", "800", "5600"};        String[] csvData4 = {"20230203", "98830901", "12984", "ord1122", "SH", "600000", "1000", "4", "1", "7.23", "1", "800", "5600"};        csvWriter2.writeLine(csvData3);        csvWriter2.writeLine(csvData4);        csvWriter2.flush();        outputStream.closeEntry();        outputStream.finish();        return "success";    } catch (Exception e) {        return "faild";    }}

总结

Java 自带的 java.util.zip 类库是一个基础的压缩和解压缩类库,它提供了很基本的压缩和解压缩功能。在处理小型文件或数据时,java.util.zip 是一个可行的选择。不过,对于大型文件或数据的处理,效率可能会受到影响。相比之下,一些第三方的类库如 Apache Commons Compress、Zip4j 等提供了更为高级的压缩和解压缩功能,同时也提供了更好的性能。
本文首发于香菜喵,打开微信随时随地读,文章下方 ↓ ↓ ↓

来源地址:https://blog.csdn.net/chen15369337607/article/details/130591293

--结束END--

本文标题: Java压缩与解压缩ZIP文件

本文链接: https://www.lsjlt.com/news/403520.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java压缩与解压缩ZIP文件
    文章目录 前言Java解压缩文件压缩和解压缩ZIP文件检验应用总结 前言 在现代计算机上,数据传输和存储越来越依赖于文件压缩技术。当我们需要发送大量数据时,压缩文件可以大大减少传输时间...
    99+
    2023-09-11
    java zip 压缩文件 解压缩文件 ZipOutputStream
  • Java实现文件压缩为zip和解压zip压缩包
    目录压缩成.zip解压.zip压缩成.zip 代码如下: public static void toZip(String srcDir, OutputStream out) th...
    99+
    2022-11-13
  • Java的zip文件压缩与解压:ZipInputStream,ZipOutputStream
    目录 文件压缩 ZipOutputStream文件解压:ZipInputStream 文件压缩 ZipOutputStream    用ZipOutputStream来压缩一个文件夹时,要搭配ZipEntry来使用。ZipEnt...
    99+
    2023-08-16
    java ZipInputStream ZipOutputStream zip
  • Java如何实现文件压缩为zip和解压zip压缩包
    本篇内容介绍了“Java如何实现文件压缩为zip和解压zip压缩包”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!压缩成.zip代码如下:pu...
    99+
    2023-07-02
  • java工具类 - 实现文件压缩zip及解压缩
    对hutool工具类进行的封装 依赖 cn.hutool hutool-all 5.8.15 ...
    99+
    2023-10-28
    java
  • 里有Java如何实现压缩与解压zip文件
    里有Java如何实现压缩与解压zip文件?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java解压缩zip - 多个文件(包括文件夹),对多个文件和文件夹进行压...
    99+
    2023-05-31
    java ava zip
  • Java如何实现ZIP压缩与解压
    Java如何实现ZIP压缩与解压,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。程序实现了ZIP压缩。共分为2部分 : 压缩(compression)与解压(de...
    99+
    2023-06-17
  • Python压缩解压缩zip文件及破解zip文件密码的方法
    python 的 zipfile 提供了非常便捷的方法来压缩和解压 zip 文件。 例如,在py脚本所在目录中,有如下文件: readability/readability.js readability...
    99+
    2022-06-04
    文件 解压缩 密码
  • 3.7Python之解压缩ZIP文件
      zip文件格式是通用的文档压缩标准。自1.6版本起,Python中zipfile模块能够直接处理zip文件里的数据,例如需要将对应目录或多个文件打包或压缩成zip格式,或者需要查看一个zip格式的归档文件中部分或者所有文件同...
    99+
    2023-01-31
    解压缩 文件 Python
  • 利用Java实现zip压缩/解压缩 (转)
    利用Java实现zip压缩/解压缩 (转)[@more@]利用Java实现zip压缩/解压缩---摘自互联网  由于网络带宽有限,所以数据文件的压缩有利于数据在Inte.NET上的快速传输,同时也节 省服务器的外存空间。   Java 1....
    99+
    2023-06-03
  • go怎么压缩和解压zip文件
    本篇内容主要讲解“go怎么压缩和解压zip文件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go怎么压缩和解压zip文件”吧!压缩zipfunc Zip(dest strin...
    99+
    2023-07-02
  • Android实现zip文件压缩及解压缩的方法
    本文实例讲述了Android实现zip文件压缩及解压缩的方法。分享给大家供大家参考。具体如下: DirTraversal.java如下: package com.once; ...
    99+
    2022-06-06
    压缩 方法 zip 解压 Android
  • linux tar.gz zip 解压缩 压缩命令
    linux tar.gz zip 解压缩 压缩命令http://apps.hi.baidu.com/share/detail/37384818download ADT linkhttp://dl.google.com/android/ADT...
    99+
    2023-06-06
  • Win10如何使用自带压缩、解压zip压缩文件功能
      Windows系统自带不少工具,到了Win10,好用的功能依然保留,比如压缩/解压zip压缩文件的功能。压缩文件能为系统节省空间,这一功能必不可少。Win10如何使用压缩/解压zip压缩文件功能?   Win10压缩...
    99+
    2023-06-10
    Win10 压缩 功能 自带 压缩文件
  • 如何利用Java实现zip压缩解压缩
    小编给大家分享一下如何利用Java实现zip压缩解压缩,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!  zip压缩文件结构:一个zip文件由多个entry组成,每...
    99+
    2023-06-03
  • python zip压缩及解压
    zipfile模块简介zipfile模块()用于压缩文件成zip及解压zip文件,模块介绍如下。·zipfile.ZipFile(file,mode)openaZIPfile,wherefilecanbeeitherapathto...
    99+
    2023-01-31
    python zip
  • go压缩解压zip文件源码示例
    目录压缩zip解压zip压缩zip func Zip(dest string, paths ...string) error { zfile, err := os.Creat...
    99+
    2022-11-13
  • java如何解压与压缩文件夹
    这篇文章将为大家详细讲解有关java如何解压与压缩文件夹,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。注意:JDK7支持设置编码设置编码格式 zipFile,zipInputStream,zipOutpu...
    99+
    2023-05-31
    java
  • Node.js中zip压缩和zip解压缩实例用法
    本篇内容主要讲解“Node.js中zip压缩和zip解压缩实例用法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node.js中zip压缩和zip解压缩实例用法...
    99+
    2022-10-19
  • Python文件的压缩与解压
    目录前言:1、压缩整个文件夹2、压缩指定扩展名文件3、获取指定类型的待压缩文件列表4、解压文件前言: Python在人工智能,后台服务等领域中得到了广泛应用。由于python有着大量...
    99+
    2022-11-10
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作