java的zip包打包

1.java的zip包打包问题

使用peazip工具能看到zip包中细微的差异
异常zip包是Method方法列中显示是空

正常zip包是Method方法列中显示的是Deflate

2.使用hutool工具打包,也不显示Deflate相关说明,

大部分情况都适用,只有在部分特殊的插件需要依赖某些zip包里目录及文件的Method属性时才有局限性,

import cn.hutool.core.util.ZipUtil;

public static void main(String[] args) throws Exception {
        // 指定要压缩的目录
        String srcDirPath = "path/to/your/directory"; // 替换为实际目录路径
        // 指定压缩后的 ZIP 文件路径
        String zipFilePath = "path/to/your/output.zip"; // 替换为实际输出 ZIP 文件路径

        // 创建 File 对象
        File srcDir = new File(srcDirPath);
        File zipFile = new File(zipFilePath);

        // 使用 Hutool 压缩目录
        ZipUtil.zip(srcDir.getAbsolutePath(), zipFile.getAbsolutePath(),true);

        System.out.println("目录已成功压缩到 ZIP 文件:" + zipFilePath);


    }

3.改造使用commons-lang包,然后手工设置deflate属性,可以实现

添加依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.21</version> <!-- 请根据需要选择合适的版本 -->
</dependency>

定义工具类

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.io.IOUtils;

import java.io.*;

public class CommonsFileUtil {
    public static void main(String[] args) {
        // 指定要压缩的目录
        String srcDirPath = "/tmp/h/demo"; // 替换为实际目录路径
        // 指定压缩后的 ZIP 文件路径
        String zipFilePath = "/tmp/h/demo.zip"; // 替换为实际输出 ZIP 文件路径

        // 创建 File 对象
        File srcDir = new File(srcDirPath);
        File zipFile = new File(zipFilePath);

        try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(new FileOutputStream(zipFile))) {
            addFileToZip(zos, srcDir, srcDir.getName() + "/");
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("目录已成功压缩到 ZIP 文件:" + zipFilePath);
    }
    private static void addFileToZip(ZipArchiveOutputStream zos, File file, String base) throws IOException {
        if (file.isDirectory()) {
            // 添加目录作为条目
            ZipArchiveEntry entry = new ZipArchiveEntry(base);
            entry.setMethod(ZipArchiveEntry.DEFLATED); // 设置为 DEFLATED 方法
            zos.putArchiveEntry(entry);
            zos.closeArchiveEntry();

            File[] files = file.listFiles();
            if (files != null) {
                for (File childFile : files) {
                    addFileToZip(zos, childFile, base + childFile.getName() + (childFile.isDirectory() ? "/" : ""));
                }
            }
        } else {
            try (FileInputStream fis = new FileInputStream(file)) {
                ZipArchiveEntry entry = new ZipArchiveEntry(base);
                entry.setMethod(ZipArchiveEntry.DEFLATED); // 设置为 DEFLATED 方法
                zos.putArchiveEntry(entry);
                IOUtils.copy(fis, zos);
                zos.closeArchiveEntry();
            }
        }
    }
}

4.扩展,zip包中的每个条目的Method的含义及意义

在 ZIP 文件中,每个条目(文件或目录)都有一个 Method 字段,该字段指定了该条目使用的压缩方法。常见的压缩方法包括:

4.1 Stored (无压缩):

Method 值:0
含义:文件或目录条目未被压缩,直接存储。
优点:快速写入和读取,因为没有压缩和解压缩的开销。
缺点:文件大小不会减少,ZIP 文件可能会很大。

4.2 Deflated (Deflate 压缩):

Method 值:8
含义:文件或目录条目使用 Deflate 算法进行压缩。
优点:通常能显著减少文件大小,使 ZIP 文件更小。
缺点:需要一些时间进行压缩和解压缩。
不同值的影响
Stored (无压缩):

4.3 适用场景

影响:ZIP 文件会更大,但读取和写入速度会更快。适用于不需要压缩的小文件或已经是压缩格式的文件(如 JPEG、MP3)。
使用场景:目录条目通常使用 Stored 方法,因为目录本身不含数据,只是一个路径。
Deflated (Deflate 压缩):

影响:ZIP 文件会更小,但读取和写入需要更多时间。适用于需要压缩的文件类型(如文本文件、未压缩的图像)。
使用场景:大多数文件条目使用 Deflate 方法,以减少 ZIP 文件的大小。
为什么目录条目通常使用 Stored 方法
目录条目不含实际数据:目录只是路径,不包含文件数据,因此没有压缩的必要。

兼容性:一些解压工具可能对压缩的目录条目支持不好,导致解析问题。使用 Stored 方法能确保更好的兼容性。
示例代码中的影响
在前面的示例代码中,如果你希望所有条目(包括目录和文件)都使用 Deflate 方法进行压缩,这可能会导致某些解压工具无法正确解析目录结构。虽然大多数现代解压工具能够处理压缩的目录条目,但为了确保最大的兼容性,通常推荐对目录条目使用 Stored 方法。

5.前端js解析zip包,分拆,组织包结构

<!DOCTYPE html>
<html><head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
</head>
<body>
    <input id="input" type="text">
    <button id="transformZipBtn">Transform Zip</button>
</body>
<script>
   let zip = new JSZip();
    let blob; // 假设你会在其他地方设置这个 blob
    function getZip(url) {
        fetch(url)
        .then(response => {
            if (response.ok) return response.blob();
            throw new Error('Network response was not ok.');
        }).then(blob => {
            zip.loadAsync(blob).then(function (zip) {
                // 处理 ZIP 文件内容
                console.log(zip.files);
            }).catch(function (e) {
                console.error('获取预览代码包失败', e);
            });
        })
        .catch(error => console.error('There was a problem with the fetch operation:', error));
    }

    // 定义一个全局函数来处理 ZIP 文件
    function transformZip() {
        let url = document.getElementById('input').value
        console.log('request url:', url);
       getZip(url);
    }

    // 使用原生 JavaScript 添加事件监听器
    document.getElementById('transformZipBtn').addEventListener('click', transformZip);
</script>

</html>
posted @ 2024-06-05 09:49  SpecialSpeculator  阅读(128)  评论(0编辑  收藏  举报