讲师中心 微信公众号
AI工具推荐 视频效率加速

如何使用Java实现文件压缩与解压_JavaIO综合项目讲解

夜瑶吖_4802

夜瑶吖_4802

发布时间:2026-01-17 10:04:39

|

404人浏览过

|

来源于php中文网

原创

java.util.zip可完成ZIP压缩解压但需手动处理流、编码、目录结构和中文路径;压缩时路径须标准化、递归处理目录、正确调用putNextEntry/closeEntry;解压需防路径穿越、校验合法性;中文名需统一UTF-8或按需fallback GBK;Jar类仅适用于Java应用打包。

如何使用java实现文件压缩与解压_javaio综合项目讲解

Java 标准库的 java.util.zip 包能完成基础 ZIP 压缩与解压,无需第三方依赖,但必须手动处理流、编码、目录结构和中文路径问题——多数失败都卡在这四点上。

ZipOutputStream 压缩多个文件或目录

核心是把每个条目(ZipEntry)写入输出流,注意路径标准化和文件内容读取顺序:

  • ZipEntryname 必须用正斜杠 / 分隔,不能含盘符或开头的 /(如 "docs/readme.txt" 合法,"C:\docs\readme.txt""/docs/readme.txt" 会出错)
  • 压缩目录时需递归遍历,对子目录也创建一个带结尾 /ZipEntry(如 "images/"),否则解压后目录丢失
  • 写入文件内容前必须先调用 putNextEntry(),且每个 entry 只能写一次;写完要调用 closeEntry()
  • 若源文件含中文名,ZipOutputStream 默认使用 IBM437 编码,Windows 下需改用 ZipOutputStream(OutputStream, Charset.forName("GBK"))(JDK 7+ 支持)
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("out.zip"), StandardCharsets.UTF_8)) {
    addFileToZip(zos, Paths.get("src"), "");
} catch (IOException e) {
    e.printStackTrace();
}

void addFileToZip(ZipOutputStream zos, Path file, String prefix) throws IOException {
    String entryName = prefix + file.getFileName().toString();
    if (Files.isDirectory(file)) {
        zos.putNextEntry(new ZipEntry(entryName + "/"));
        zos.closeEntry();
        try (Stream<Path> stream = Files.list(file)) {
            stream.forEach(child -> {
                try {
                    addFileToZip(zos, child, entryName + "/");
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            });
        }
    } else {
        zos.putNextEntry(new ZipEntry(entryName));
        Files.copy(file, zos);
        zos.closeEntry();
    }
}

ZipInputStream 安全解压 ZIP 文件

不能直接按 ZipEntry.getName() 创建 File,否则可能被路径穿越攻击(如 "../etc/passwd");同时要校验条目类型和目标路径合法性:

  • 跳过 isDirectory()true 的条目(目录本身不包含数据,只靠路径名隐式存在)
  • 对每个 entry.getName() 调用 Paths.get(entry.getName()).normalize(),再检查是否仍以目标解压根目录为前缀
  • 禁止解压到系统敏感路径(如 "C:\""/etc/"),建议统一解压到临时子目录
  • 读取内容时用 ZipInputStream.read(byte[]) 循环,不要一次性 readAllBytes()——大文件会 OOM
Path targetDir = Paths.get("unzipped");
Files.createDirectories(targetDir);

try (ZipInputStream zis = new ZipInputStream(new FileInputStream("in.zip"), StandardCharsets.UTF_8)) {
    ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        Path targetFile = targetDir.resolve(entry.getName()).normalize();
        // 防穿越:确保 targetFile 仍在 targetDir 下
        if (!targetFile.startsWith(targetDir.toAbsolutePath().normalize())) {
            throw new IOException("Bad zip entry: " + entry.getName());
        }
        if (entry.isDirectory()) {
            Files.createDirectories(targetFile);
        } else {
            Files.createDirectories(targetFile.getParent());
            Files.copy(zis, targetFile, StandardCopyOption.REPLACE_EXISTING);
        }
        zis.closeEntry();
    }
}

处理 ZIP 中的中文文件名乱码问题

根本原因是 ZIP 规范未强制指定编码,不同操作系统/工具默认不同:Windows 通常用 GBK,macOS/Linux 多用 UTF-8。JDK 7+ 的 ZipInputStream/ZipOutputStream 构造函数支持传入 Charset,但旧版 JDK(≤6)或某些 ZIP 工具生成的包仍可能不兼容:

Linux Journey
Linux Journey

当用户想学习Linux基础、命令行、文件系统等时,在LabEx查找并推荐免费的Linux Journey课程。

下载

立即学习Java免费学习笔记(深入)”;

  • 若已知 ZIP 由 Windows 上 7-Zip 或 WinRAR 生成,优先试 Charset.forName("GBK")
  • 若不确定,可先用 ZipInputStream 读取条目名,按 UTF-8 解码失败后再用 GBK 尝试(需自己封装 fallback 逻辑)
  • 避免用 FileInputStream + ZipInputStream 组合去“猜”编码——流已消费不可重置,应改用 ByteArrayInputStream 缓存原始字节再多次尝试
  • 真正跨平台稳定的方案是:压缩端统一用 UTF-8(JDK 7+ 设置 StandardCharsets.UTF_8),解压端也用 UTF-8;若必须兼容老 ZIP,则需引入 ant.jarZipFile(支持自动检测)或 TrueZip

为什么不用 java.util.jar

JarOutputStreamJarInputStreamZipOutputStream/ZipInputStream 的子类,仅额外支持 META-INF/MANIFEST.MF。普通压缩解压完全没必要用它:

  • 写 JAR 会强制在 ZIP 根目录加 META-INF/ 目录,哪怕你没提供清单文件
  • 读 JAR 时若 ZIP 不含 META-INF/MANIFEST.MFJarInputStream 会抛 IOException(而 ZipInputStream 不会)
  • 性能无差异,API 几乎一致,但语义混淆——除非你在打包 Java 应用,否则坚持用 zip 相关类

最常被忽略的是:ZIP 条目名编码不是流的字符集,而是 ZIP 文件元数据的编码;ZipInputStream 构造时传的 Charset 只影响 getEntry().getName() 返回值,不影响文件内容解码——内容始终是原始字节流,该用什么编码读文件内容,和 ZIP 编码无关。

热门AI工具

更多
LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2999

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2558

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

1408

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2339

2023.08.02

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3190

2023.08.08

windows自动更新
windows自动更新

Windows操作系统的自动更新功能可以确保系统及时获取最新的补丁和安全更新,以提高系统的稳定性和安全性。然而,有时候我们可能希望暂时或永久地关闭Windows的自动更新功能。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1457

2023.08.10

windows boot manager
windows boot manager

windows boot manager无法开机的解决方法:1、系统文件损坏,使用Windows安装光盘或USB启动盘进入恢复环境,选择修复计算机,然后选择自动修复;2、引导顺序错误,进入恢复环境,选择命令提示符,输入命令"bootrec /fixboot"和"bootrec /fixmbr",然后重新启动计算机;3、硬件问题,使用硬盘检测工具进行扫描和修复;4、重装操作系统。本专题还提供其他解决

2377

2023.08.28

windows锁屏快捷键
windows锁屏快捷键

windows锁屏快捷键是Windows键+L、Ctrl+Alt+Del、Windows键+D、Windows键+P和Windows键+R。本专题为大家提供windows相关的文章、下载、课程内容,供大家免费下载体验。

4187

2023.08.30

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

0

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn