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>