You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java中压缩大量相似JSON字节数组 实现更高ZIP压缩率

问题核心原因

JDK 内置的 ZipOutputStream 默认采用单文件独立压缩逻辑,每写入完一个 ZipEntry 就会重置压缩字典,3万个结构相似的JSON文件之间的重复内容无法被跨文件复用,因此压缩率只能到50%左右。你二次嵌套压缩时,整个低压缩率的ZIP包被作为单个文件处理,包内大量重复的压缩块特征被识别,所以能达到99%的极高压缩率。

可行解决方案

方案1:使用Apache Commons Compress生成固实压缩ZIP(推荐)

固实压缩是ZIP格式支持的特性,所有文件共享同一个压缩字典,完全可以识别跨文件的重复内容,生成的压缩包和标准ZIP格式完全兼容,无需二次解压。
代码示例:

import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import java.io.FileOutputStream;
import java.util.List;

public class HighCompressZip {
    public static void main(String[] args) throws Exception {
        List<byte[]> listOfbyteArrays = ...; // 你的字节数组列表
        int fileCount = 0;
        try (ZipArchiveOutputStream out = new ZipArchiveOutputStream(new FileOutputStream("high_compress_out.zip"))) {
            // 最高压缩级别
            out.setLevel(9);
            // 适配超过4GB的大文件场景
            out.setUseZip64(ZipArchiveOutputStream.Zip64Mode.Always);
            // 开启固实压缩,核心配置:共享压缩字典
            out.setSolidArchive(true);
            
            for (byte[] byteArray : listOfbyteArrays) {
                var entry = out.createArchiveEntry(null, fileCount++ + ".json");
                out.putArchiveEntry(entry);
                out.write(byteArray);
                out.closeArchiveEntry();
            }
        }
    }
}

该方案生成的压缩包压缩率和你二次嵌套压缩的效果基本一致,所有常见解压工具都可以直接打开读取里面的单个JSON文件。

方案2:JDK原生嵌套压缩实现(无第三方依赖)

如果不想引入第三方库,可以直接在内存中模拟嵌套压缩的逻辑,先把所有JSON打包成无压缩的ZIP包保留原始重复特征,再把整个无压缩包作为单个文件压缩,也能达到同等压缩效果。
代码示例:

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class NativeNestedZip {
    public static void main(String[] args) throws Exception {
        List<byte[]> listOfbyteArrays = ...; // 你的字节数组列表
        int fileCount = 0;
        
        // 第一步:生成无压缩的内层ZIP,保留所有JSON的重复内容
        ByteArrayOutputStream innerZipBaos = new ByteArrayOutputStream();
        try (ZipOutputStream innerOut = new ZipOutputStream(innerZipBaos)) {
            innerOut.setLevel(0); // 禁用压缩
            for (byte[] byteArray : listOfbyteArrays) {
                innerOut.putNextEntry(new ZipEntry(fileCount++ + ".json"));
                innerOut.write(byteArray);
                innerOut.closeEntry();
            }
        }
        
        // 第二步:把整个内层ZIP作为单个文件压缩到最终压缩包
        try (ZipOutputStream finalOut = new ZipOutputStream(new FileOutputStream("final_out.zip"))) {
            finalOut.setLevel(9); // 最高压缩级别
            finalOut.putNextEntry(new ZipEntry("data.zip"));
            finalOut.write(innerZipBaos.toByteArray());
            finalOut.closeEntry();
        }
    }
}

该方案仅用JDK内置类,无需额外依赖,缺点是解压时需要先解压外层压缩包得到data.zip,再解压内层包才能拿到单个JSON文件。

额外优化建议

如果你的JSON结构高度固定,可以提前提取所有高频出现的字符串(比如公共key、固定前缀等)拼接为自定义压缩字典,传入压缩器使用,压缩率还能进一步提升:

// 示例:提前构造公共字典,替换为你实际业务中的高频字符串
byte[] commonDict = "{\"id\",\"userId\",\"timestamp\",\"content\",\"extInfo\"}".getBytes();
Deflater deflater = new Deflater(9, true);
deflater.setDictionary(commonDict);
// 将自定义deflater传入ZipOutputStream即可生效

内容的提问来源于stack exchange,提问作者slartidan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:45:02