当前位置: 首页 > news >正文

Java学习之——“IO流“的进阶流之压缩流的学习

一、压缩流核心概念

        Java 的压缩流并不是一种独立的流,而是一组基于装饰器模式的过滤流(处理流)。它们“装饰”在基本的字节流之上,在写入数据时自动进行压缩,在读取数据时自动进行解压缩。

        核心思想:在IO传输过程中,动态地对字节数据进行压缩或解压,从而节省存储空间或网络带宽。

        ZIP 压缩流是 Java 中处理 ZIP 格式文件的核心 API,它允许我们以编程方式创建、读取和修改 ZIP 压缩文件。

Java 处理 ZIP 文件主要依赖于 java.util.zip 包中的以下几个核心类:

类名作用描述
ZipOutputStream用于创建 ZIP 压缩文件并向其中添加条目
ZipInputStream用于读取 ZIP 压缩文件并提取其中的条目
ZipEntry表示 ZIP 文件中的一个压缩条目(文件或目录)
ZipFile提供了另一种读取 ZIP 文件的方式,支持随机访问

基本压缩流程

创建 ZIP 文件的基本流程是:

  • 创建 FileOutputStream 指向目标 ZIP 文件
  • 使用 ZipOutputStream 包装该输出流
  • 为每个要压缩的文件创建 ZipEntry 并添加到 ZIP 流
  • 将文件内容写入到对应的 ZIP 条目
  • 关闭所有资源

基本解压流程

解压 ZIP 文件的基本流程是:

  • 创建 FileInputStream 指向 ZIP 文件
  • 使用 ZipInputStream 包装该输入流
  • 循环获取 ZIP 文件中的每个条目
  • 为每个条目创建对应的文件/目录
  • 将条目内容写入到目标文件
  • 关闭所有资源

二、ZipEntry作用的详解

        ZipEntry 是 Java 的 java.util.zip 包中的一个类。它的核心作用代表一个ZIP压缩文件中的单个条目(entry)。 你可以把它理解为一个ZIP文件内部的“元数据”或“目录项”,它描述了压缩包中每一个文件或目录的信息,但它本身并不包含文件的实际数据内容。

简单来说:

  • 一个 ZipFile 或 ZipInputStream 对象代表整个ZIP文件。
  • 一个 ZipEntry 对象代表ZIP文件里面的一个具体文件(如 document.txt)或目录(如 images/)。

        ZipInputStream 是用于按顺序读取ZIP文件数据流的通道,而 ZipEntry 则是这个流中每个独立文件单元的元数据标识和分隔符。

核心作用详解

ZipEntry 的主要作用可以分为以下几个方面:

1. 元数据描述

        这是 ZipEntry 最基本和最重要的作用。它存储了ZIP条目(即压缩包里的一个文件)的详细信息,包括:

  • 名称 (getName()): 条目在ZIP文件中的路径和文件名,例如 "data/config.json" 或 "photos/2024/summer.jpg"
  • 压缩后大小 (getCompressedSize()): 文件被压缩后在ZIP包中所占的字节数。
  • 原始大小 (getSize()): 文件未压缩时的原始字节数。如果未知,则返回 -1
  • CRC-32 校验和 (getCrc()): 用于验证解压后数据的完整性。将解压出的数据计算出的CRC值与这里存储的值对比,可以判断数据是否损坏。
  • 修改时间 (getTime()): 文件最后一次修改的时间(自公元纪年开始的毫秒数)。
  • 压缩方法 (getMethod()): 文件使用的压缩算法。通常是 DEFLATED(压缩)或 STORED(不压缩,仅存储)。
  • 注释 (getComment()): 条目的可选注释信息。
2. 数据提取的桥梁

        当您想从ZIP文件中读取(解压)某个特定文件时,ZipEntry 是关键桥梁。流程通常是:

  • 通过 ZipInputStream 或 ZipFile 遍历ZIP文件,获取下一个 ZipEntry
  • 检查这个 ZipEntry 的名称,确定它是不是你想要的文件。
  • 如果是要找的文件,然后 再从 ZipInputStream 中读取该条目对应的实际压缩数据,并进行解压。
// 示例:使用 ZipInputStream 读取ZIP文件中的第一个条目
try (ZipInputStream zis = new ZipInputStream(new FileInputStream("archive.zip"))) {// 获取ZIP文件中的第一个条目(entry)ZipEntry entry = zis.getNextEntry();if (entry != null) {System.out.println("正在解压: " + entry.getName());System.out.println("原始大小: " + entry.getSize());// 现在,从 zis 中读取的数据就是这个 entry 对应的文件内容byte[] buffer = new byte[1024];int len;while ((len = zis.read(buffer)) > 0) {// 将 buffer 中的数据写入到目标文件// ...}// 关闭当前条目,准备读取下一个zis.closeEntry();}
}

三、压缩流代码示例

1.压缩

压缩单个文件

import java.io.*;
import java.util.zip.*;public class ZipSingleFileExample {public static void main(String[] args) {String sourceFile = "document.txt";String zipFile = "compressed.zip";try (FileOutputStream fos = new FileOutputStream(zipFile);ZipOutputStream zos = new ZipOutputStream(fos);FileInputStream fis = new FileInputStream(sourceFile)) {// 创建ZIP条目ZipEntry zipEntry = new ZipEntry(sourceFile);zos.putNextEntry(zipEntry);// 设置压缩级别 (0-9)zos.setLevel(Deflater.BEST_COMPRESSION);// 将文件内容写入ZIPbyte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) >= 0) {zos.write(buffer, 0, length);}// 关闭当前条目zos.closeEntry();System.out.println("文件压缩完成: " + zipFile);} catch (IOException e) {e.printStackTrace();}}
}

压缩多个文件

import java.io.*;
import java.util.zip.*;public class ZipMultipleFilesExample {public static void main(String[] args) {String[] filesToZip = {"file1.txt", "file2.txt", "image.jpg"};String zipFile = "archive.zip";try (FileOutputStream fos = new FileOutputStream(zipFile);ZipOutputStream zos = new ZipOutputStream(fos)) {// 设置压缩级别zos.setLevel(Deflater.DEFAULT_COMPRESSION);for (String file : filesToZip) {try (FileInputStream fis = new FileInputStream(file)) {// 为每个文件创建ZIP条目ZipEntry zipEntry = new ZipEntry(file);zos.putNextEntry(zipEntry);// 写入文件内容byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) >= 0) {zos.write(buffer, 0, length);}// 关闭当前条目zos.closeEntry();} catch (IOException e) {System.err.println("处理文件时出错: " + file);e.printStackTrace();}}System.out.println("多文件压缩完成: " + zipFile);} catch (IOException e) {e.printStackTrace();}}
}

压缩目录(包含子目录)

import java.io.*;
import java.util.zip.*;public class ZipDirectoryExample {public static void main(String[] args) {String sourceDir = "docs";String zipFile = "docs.zip";try (FileOutputStream fos = new FileOutputStream(zipFile);ZipOutputStream zos = new ZipOutputStream(fos)) {zipDirectory(sourceDir, sourceDir, zos);System.out.println("目录压缩完成: " + zipFile);} catch (IOException e) {e.printStackTrace();}}private static void zipDirectory(String rootDir, String sourceDir, ZipOutputStream zos) throws IOException {File dir = new File(sourceDir);File[] files = dir.listFiles();if (files == null) return;for (File file : files) {if (file.isDirectory()) {// 递归处理子目录zipDirectory(rootDir, file.getAbsolutePath(), zos);continue;}try (FileInputStream fis = new FileInputStream(file)) {// 创建相对路径的ZIP条目String zipPath = file.getAbsolutePath().substring(new File(rootDir).getAbsolutePath().length() + 1);ZipEntry zipEntry = new ZipEntry(zipPath);zos.putNextEntry(zipEntry);// 写入文件内容byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) >= 0) {zos.write(buffer, 0, length);}zos.closeEntry();}}}
}

2.解压缩

import java.io.*;
import java.util.zip.*;public class UnzipExample {public static void main(String[] args) {String zipFile = "archive.zip";String destDirectory = "extracted";// 创建目标目录File destDir = new File(destDirectory);if (!destDir.exists()) {destDir.mkdir();}try (FileInputStream fis = new FileInputStream(zipFile);ZipInputStream zis = new ZipInputStream(fis)) {ZipEntry entry;while ((entry = zis.getNextEntry()) != null) {String filePath = destDirectory + File.separator + entry.getName();// 防止ZIP Slip攻击File destFile = new File(filePath);String canonicalDestPath = destFile.getCanonicalPath();String canonicalDestDir = destDir.getCanonicalPath();if (!canonicalDestPath.startsWith(canonicalDestDir + File.separator)) {throw new IOException("恶意ZIP文件: 尝试解压到非法路径 " + entry.getName());}if (entry.isDirectory()) {// 创建目录if (!destFile.exists()) {destFile.mkdirs();}} else {// 确保父目录存在File parent = destFile.getParentFile();if (!parent.exists()) {parent.mkdirs();}// 解压文件try (FileOutputStream fos = new FileOutputStream(destFile);BufferedOutputStream bos = new BufferedOutputStream(fos)) {byte[] buffer = new byte[1024];int length;while ((length = zis.read(buffer)) >= 0) {bos.write(buffer, 0, length);}}}zis.closeEntry();}System.out.println("ZIP文件解压完成到: " + destDirectory);} catch (IOException e) {e.printStackTrace();}}
}

文章转载自:

http://1xQdKbd1.bLdmb.cn
http://h3tHC0Gd.bLdmb.cn
http://VJ6iZxcp.bLdmb.cn
http://NgzgYyOA.bLdmb.cn
http://2SqZZHsu.bLdmb.cn
http://Mrig5pth.bLdmb.cn
http://LWTxMkUG.bLdmb.cn
http://ZpuSIS2M.bLdmb.cn
http://Yz0SljOm.bLdmb.cn
http://kEM9uWJ3.bLdmb.cn
http://AM51VDLz.bLdmb.cn
http://Tv3L4FJC.bLdmb.cn
http://lCzWd9Xh.bLdmb.cn
http://cFuT7ow5.bLdmb.cn
http://lbEhNRqT.bLdmb.cn
http://mXCPaNi7.bLdmb.cn
http://2SB8YwNL.bLdmb.cn
http://R8w1nPyY.bLdmb.cn
http://EFpOfnyz.bLdmb.cn
http://fySzLajn.bLdmb.cn
http://4efQjKAn.bLdmb.cn
http://gPxJyrOo.bLdmb.cn
http://niFycUcV.bLdmb.cn
http://hLvQHEdN.bLdmb.cn
http://mdIzsRcL.bLdmb.cn
http://wDUWvDHi.bLdmb.cn
http://jAmNoZ7Q.bLdmb.cn
http://4AvWxt2j.bLdmb.cn
http://gpjCXtFW.bLdmb.cn
http://rTqkJi10.bLdmb.cn
http://www.dtcms.com/a/381221.html

相关文章:

  • 2025在校大学生可以考哪些大数据专业证书?
  • cte功能oracle与pg执行模式对比
  • 铁路轨道扣件破损视觉检测方案
  • 解释一下C++中内存屏障和它的作用——多线程编程
  • 文献速递 | 徐国良/邵振/陈辉合作揭示DNA甲基化抑制性别决定区的减数分裂重组
  • 如何让 RAG 的检索精准度提升 80%?
  • 镀锌板数控矫平机科普
  • 日志的查看与管理
  • Redis + MySQL 的缓存一致性
  • 2025最新中文字体下载免费网站整理,商用无版权风险!
  • Flutter 数据存储的四种核心方式 · 从 SharedPreferences 到 SQLite:Flutter 数据持久化终极整理
  • 容器问答题下
  • 题目:盛水最多的容器(medium)
  • win7 R 4.4.0和RStudio1.25的版本兼容性以及系统区域设置有关 导致Plots绘图面板被禁用,但是单独页面显示
  • 中级统计师-统计法规-第六章 统计行政许可制度
  • Coze源码分析-资源库-创建知识库-前端源码-核心逻辑与接口
  • MySQL数据库-03(字段的约束)
  • Secure Boot 的Linux系统中添加模块
  • 内存泄漏的危害(Memory Leak)
  • Linux进程概念(中):进程优先级和环境变量
  • 【完整源码+数据集+部署教程】X片唇部实例分割系统源码和数据集:改进yolo11-swintransformer
  • 【.Net技术栈梳理】08-控制反转(IoC)与依赖注入(DI)
  • GFSK调制解调介绍(蓝牙GFSK BT=0.5)
  • 【202509新版】Hexo + GitHub Pages 免费部署个人博客|保姆级教程 第二部
  • 【算法--链表】147.对链表进行插入排序--通俗讲解
  • 亚马逊产品转化怎么提高?从传统运营到智能优化的深度解析
  • 第七章:顶点的魔力-Vertex Magic《Unity Shaders and Effets Cookbook》
  • SSM整合(统一响应,拦截器)
  • GESP图形化1~2级拓展课二
  • Lazada自养号测评系统搭建:技术要点与策略解析