java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java ZipOutputStream压缩

Java利用ZipOutputStream进行高效压缩的技巧详解

作者:心之语歌

ZipOutputStream 是 Java 标准库中用于 创建 ZIP 文件 的核心类,位于 java.util.zip 包中,本文主要和大家介绍了Java如何使用ZipOutputStream进行高效压缩,有需要的可以了解下

简介

ZipOutputStream 是 Java 标准库中用于 创建 ZIP 文件 的核心类,位于 java.util.zip 包中。它允许你将多个文件或字节流写入一个 ZIP 压缩包,并支持设置压缩级别、编码方式等参数。

基本概念

ZipOutputStream的作用

常用方法说明

方法描述
putNextEntry(ZipEntry entry)开始写入一个新的 ZIP 条目(文件)
closeEntry()关闭当前 ZIP 条目,准备写入下一个
write(byte[] b, int off, int len)写入当前条目的内容(字节数据)
setLevel(int level)设置压缩级别(0~9)
setComment(String comment)设置整个 ZIP 文件的注释
finish()完成写入,但不关闭底层输出流(可选)

可选的压缩级别(取值范围:0 ~ 9)

级别含义特点
Deflater.NO_COMPRESSION (0)不压缩速度最快,ZIP 文件最大
Deflater.BEST_SPEED (1)最快压缩压缩率低,速度快
Deflater.DEFAULT_COMPRESSION (6)默认压缩平衡压缩率与速度
Deflater.BEST_COMPRESSION (9)最佳压缩压缩率最高,速度最慢

本地保存

import java.io.*;
import java.nio.file.*;
import java.util.zip.*;

public class ZipDemo {
    public static void main(String[] args) throws IOException {
        // 源文件夹路径:要压缩的文件所在的目录
        String sourceDir = "path/to/folder";

        // 输出 ZIP 文件路径:生成的压缩包保存的位置和名称
        String zipFilePath = "output.zip";

        // 使用 try-with-resources 自动关闭资源(FileOutputStream 和 ZipOutputStream)
        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            // 设置 ZIP 压缩级别为最佳压缩(压缩率最高,但速度较慢)
            zos.setLevel(Deflater.BEST_COMPRESSION);

            // 遍历源目录下的所有文件(包括子目录中的文件)
            Files.walk(Paths.get(sourceDir))
                 // 过滤掉目录,只保留文件
                 .filter(path -> !Files.isDirectory(path))
                 // 对每个文件执行以下操作
                 .forEach(path -> {
                     try {
                         // 构建相对路径字符串:sourceDir + 文件分隔符 + 文件名
                         // 注意:这会导致 ZIP 中的路径包含 sourceDir 的前缀
                         String relativePath = sourceDir + File.separator + path.getFileName();

                         // 创建一个 ZIP 条目(即 ZIP 包中的一个文件)
                         ZipEntry zipEntry = new ZipEntry(relativePath);

                         // 开始写入该条目到 ZIP 流中
                         zos.putNextEntry(zipEntry);

                         // 读取文件内容为字节数组
                         byte[] bytes = Files.readAllBytes(path);

                         // 将文件内容写入 ZIP 输出流
                         zos.write(bytes, 0, bytes.length);

                         // 关闭当前 ZIP 条目,准备写入下一个文件
                         zos.closeEntry();

                     } catch (IOException e) {
                         // 如果写入失败,打印错误信息并输出异常堆栈
                         System.err.println("写入 ZIP 失败: " + path);
                         e.printStackTrace();
                     }
                 });
        }
        // try-with-resources 会自动关闭 fos 和 zos,无需手动 close()
    }
}

ZIP 文件网络流下载

response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"streamed_files.zip\"");

try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8)) {
    zipOut.setLevel(Deflater.BEST_SPEED);

    for (User u : userList) {
        String fileName = String.format("%sxxxx.docx", u.getNickName());

        try {
            zipOut.putNextEntry(new ZipEntry(fileName));
            byte[] docBytes = genDocx(u).toByteArray();
            zipOut.write(docBytes, 0, docBytes.length);
            zipOut.closeEntry();
        } catch (IOException e) {
            log.error("写入 ZIP 条目失败: {}", fileName, e);
            throw new IOException("生成 ZIP 条目时出错: " + fileName, e);
        }
    }

} catch (IOException ex) {
    log.error("导出 ZIP 异常", ex);
    throw new RuntimeException("导出异常");
}

1. 设置响应头

response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=\"streamed_files.zip\"");

2. 创建 ZIP 输出流(使用 try-with-resources)

try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8)) {

注意:部分旧系统或工具(如 Windows 自带解压器)可能不识别 UTF-8 编码的 ZIP 文件名,建议使用 7-Zip、WinRAR 或 Mac 解压工具。

3. 设置压缩级别(可选)

zipOut.setLevel(Deflater.BEST_SPEED);

4. 生成文件加入到 zip 流

zipOut.putNextEntry(new ZipEntry(fileName));
byte[] docBytes = genDocx(u).toByteArray();
zipOut.write(docBytes, 0, docBytes.length);
zipOut.closeEntry();

关闭当前 ZIP 条目,准备写入下一个文件。

到此这篇关于Java利用ZipOutputStream进行高效压缩的技巧详解的文章就介绍到这了,更多相关Java ZipOutputStream压缩内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文