跳转到内容

zip - 压缩与解压

更新: 2025/7/20 字数: 0 字 时长: 0 分钟

Stability: 2 - Stable

Zip模块用于处理文件的压缩和解压,并支持加密压缩。

zip功能来自zip4j ,可阅读相关文档获取更多信息。

视频教程

观看提示

哔哩哔哩默认仅支持 360P 清晰度,为了获得更清晰的视频画质,请手动切换至 720P 或更高清 画质。

$zip.zipDir(dir, dest[, options])

  • dir {string} 需要压缩的文件夹路径,如果文件夹下有子文件夹均会一并压缩
  • dest {string} 压缩后的压缩包存放路径
  • options {object} 可选参数,选项option包括以下内容,完整的选项参见压缩选项
    • password {string} 加密压缩的密码。如果设置密码但不设置加密方法,则加密方法默认为AES
    • compressionMethod {string} 压缩方式,COMP_STORE为仅打包不压缩, COMP_DEFLATE为压缩(默认)
    • encryptionMethod {string} 加密方法,ENC_NO_ENCRYPTION为不加密(默认),ENC_METHOD_STANDARD为标准机密, ENC_METHOD_AES为AES加密
    • compressionLevel {number} 压缩级别,0~9,0为不压缩,9为最好压缩(速度较慢)。在8.7以前版本,默认为0不压缩;在8.7以后,该值默认为5(正常压缩)
    • aesKeyStrength {string} AES加密强度,包括AES_STRENGTH_128AES_STRENGTH_192AES_STRENGTH_256
    • readHiddenFiles {boolean} 压缩文件夹时是否包含隐藏文件。如果为true,则在将文件夹添加到zip时将包含隐藏文件
    • includeRootFolder {boolean} 设置标志以指示添加文件的父文件夹是否将包含在ZIP中。如果为true,则添加文件的父文件夹将包含在ZIP中。默认true
    • rootFolderInZip {string} 设置压缩包首目录的文件夹名称,如果没有首目录,则创建这个首目录

压缩文件夹下所有文件/文件夹,生成到目标路径dest

一个简单的压缩文件夹例子。

js
// 需压缩文件路径
let dir = "./zipExample2/";
// 压缩后文件存放路径
if (!$files.exists(dir)) {
    // 文件夹不存在 创建文件夹 
    $files.create(dir); 
}
 // 创建一个文件,自己可多放几个文件或文件夹运行看效果
 $files.create($files.join(dir, "test.js"));
// 压缩后文件存放路径
let zipFile = $files.join(dir, "未加密压缩.zip");
 // 删除同名文件
$files.remove(zipFile);
// 压缩
$zip.zipDir(dir, zipFile);
log("压缩完成,压缩包路径:" + zipFile);

加密压缩例子

js
// 需压缩文件路径
let dir = "./zipExample2/";
// 压缩后文件存放路径
if (!$files.exists(dir)) {
    // 文件夹不存在 创建文件夹 
    $files.create(dir); 
}
 // 创建一个文件,自己可多放几个文件或文件夹运行看效果
 $files.create($files.join(dir, "test.js"));
// 压缩包存放路径
let encryptedZipFile = $files.join(dir, "加密压缩.zip"); 
$files.remove(encryptedZipFile); // 删除同名文件
// 压缩
$zip.zipDir(dir, encryptedZipFile, {
    password: "Bot.js Pro" ,// 压缩密码
    compressionLevel: 5, // 压缩级别
    aesKeyStrength: 'AES_STRENGTH_256', // 加密方法
    readHiddenFiles: false, // 隐藏文件不添加进压缩包
    includeRootFolder: false, //不添加文件夹父目录进压缩包
    rootFolderInZip: "测试" // 为压缩包添加一个父目录
});
log("加密压缩完成,压缩包路径:" + encryptedZipFile);

$zip.zipFile(file, dest[, options])

  • file {string} 需要压缩的单文件路径。
  • dest {string} 压缩后的压缩包存放路径
  • options {object} 选项参见参见压缩选项

压缩单文件file到路径dest

js
let path = "./zipExample/test.js";
if (!$files.exists(path)) {
    $files.create(path);
}
let zipFilePath = "./zipExample/test.zip";
$zip.zipFile(path, zipFilePath);
log("单文件压缩完成,压缩包路径:" + zipFilePath);

$zip.zipFiles(fileList, dest[, options])

  • fileList {string[]} 需压缩的多个文件路径的数组
  • dest {string} 压缩目标路径
  • options {object} 选项参见压缩选项

压缩多个文件fileList到路径destfileList中不能包含文件夹。

js
let dir = "./zipExample3/";
if (!$files.exists(dir)) {
    $files.create(dir);
}
let fileList = ["file1.js", "file2.js", "file3.js"].map(p => $files.join(dir, p));
fileList.forEach(file => {
        $files.create(file);
});

let zipMultiFile = $files.join(dir, "多文件压缩.zip");
$files.remove(zipMultiFile); // 删除同名文件
$zip.zipFiles(fileList, zipMultiFile); // 压缩
log("多文件压缩完成,压缩包路径:" + zipMultiFile);

$zip.unzip(zipFile, dest[, options])

  • zipFile {string} 需解压的压缩包文件路径
  • dest {string} 解压后的文件夹目录
  • options {object} 解压选项,可选,参见解压选项

解压zip文件。如果文件夹dest不存在则创建该文件夹并将内容解压到里面;如果dest已经存在,则在dest下面创建一个和zipFile文件同名的文件夹,并将内容解压到里面。

js
// 准备一个加密的压缩包
let dir = "./zipExample2/";
if (!$files.exists(dir)) {
    $files.create(dir);
}
// 压缩后文件存放路径
let encryptedZipFile = $files.join(dir, "加密压缩.zip");
$files.remove(encryptedZipFile); // 删除同名文件
// 压缩
$zip.zipDir(dir, encryptedZipFile, {
    password: "Bot.js Pro" // 压缩密码
});

$zip.unzip(encryptedZipFile, './zipExample5', {
    password: 'Bot.js Pro' // 解压密码
});
log("加密zip解压成功,解压路径:" + "./zipExample5/");

$zip.open(file)

  • file {string} 压缩包文件路径
  • 返回 {ZipFile} ZipFile对象

打开一个zip文件,返回ZipFile对象,可对该对象进行进一步的zip操作。

ZipFile

$zip.open()返回的对象,用于在压缩包中增删文件、获取文件头信息、解压等。

ZipFile.getPath()

  • 返回 {string} 返回路径

获取当前压缩包的路径。

js
let path = "./test.zip";
let zipFile = $zip.open(path);
log(zipFile.getPath());
// 输出路径 "./test.zip"

ZipFile.isValidZipFile()

  • 返回 {boolean} 是否是有效压缩包

获取当前压缩包是否是一个有效的压缩包。

如果选择的路径不是一个压缩包或该文件不存在,均返回false

ZipFile.setPassword(password)

  • password {string} 设置密码

如果文件是一个加密的压缩包,必须用此函数设置正确的解压密码,才能解压出加密的文件。

未设置密码尝试解压加密的压缩包将抛出异常,选择的压缩包文件不存在使用本函数将抛出ZipException

ZipFile.isEncrypted()

  • 返回 {boolean} 是否压缩包加密

获取当前压缩包是否是加密压缩包。

ZipFile.addFile(file[, options])

  • file {string} 本地文件路径
  • options {object} 压缩选项,可选,参见压缩选项

在压缩包中添加指定文件。

js
let zipFile = $zip.open("./app.apk");
zipFile.addFile(file);

ZipFile.addFiles(fileList, options)

  • fileList {string[]} 要添加的本地文件路径的数组
  • options {object} 压缩选项,可选,参见压缩选项

在压缩包中添加多个文件。

ZipFile.addFolder(folder[, options])

  • folder {string} 文件夹路径
  • options {object} 压缩选项,可选,参见压缩选项

在压缩包中添加指定文件夹。

注意

注意不要添加压缩包的父目录,否则可能造成循环无限添加!

一个备份脚本的简单例子:

js
let zipFile = "/sdcard/scripts.zip";
 //指定压缩包文件
let zip = $zip.open(zipFile);
log("开始备份,取决与你的脚本数量");
// 向压缩包添加当前文件夹
zip.addFolder("./"); 
log("备份完成,压缩包路径为:" + zipFile);

ZipFile.removeFile(file)

  • file {string} 要删除的文件

删除zip文件内的指定文件。此方法首先找到文件头,然后删除文件;如果文件不存在,则此方法引发异常。

如果zip文件是分割后的zip文件,则此方法会抛出异常,原因是zip规范不允许更新拆分的zip档案。

js
let zipFile = $zip.open("./app.apk");
zipFile.removeFile("res/drawable/logo.png");

ZipFile.extractFile(file, dest[, options, newFileName])

  • file {string} 要解压的文件
  • dest {string} 解压文件的目标路径
  • options {Object} 解压选项,可选。参见解压选项
  • newFileName {string} 解压后文件的新名字,可选.

从压缩包文件中提取特定文件到目标路径。如果目标路径无效,则此方法将引发异常。

ZipFile.extractAll(dest{, options})

  • dest {string} 解压路径
  • options {Object} 解压选项,可选。参见解压选项

解压所有文件到目标路径dest

js
let zip = $zip.open("./test.zip");
zip.addFiles(["./test.js", "./test.txt"]);
zip.extractAll("./test");

ZipFile.getFileHeader(file)

  • file {string} 压缩包内指定文件路径
  • 返回 {FileHeader }

获取压缩包内指定文件的文件头信息。文件头信息包括校验值,是否加密,注释等。

ZipFile.getFileHeaders()

获取压缩包内所有文件的文件头信息。文件头信息包括校验值,是否加密,注释等。

压缩选项

options {object} 包括:

  • aesKeyStrength {string} AES加密强度,包括AES_STRENGTH_128AES_STRENGTH_192AES_STRENGTH_256
  • compressionLevel {number} 压缩级别,0~9,0为不压缩,9为最好压缩(速度较慢)。在8.7以前版本,默认为0不压缩;在8.7以后,该值默认为5(正常压缩)
  • compressionMethod {string} 压缩方式,COMP_STORE为仅打包不压缩, COMP_DEFLATE为压缩(默认)
  • defaultFolderPath {string} 压缩或添加文件时,指定文件在压缩包的默认文件夹位置
  • encryptionMethod {string} 加密方法,ENC_NO_ENCRYPTION为不加密(默认),ENC_METHOD_STANDARD为标准机密, ENC_METHOD_AES为AES加密
  • fileNameInZip {string} 压缩或添加文件时,指定文件在压缩包中的路径、名称
  • includeRootFolder {boolean} 设置标志以指示添加文件的父文件夹是否将包含在ZIP中。如果为true,则添加文件的父文件夹将包含在ZIP中。默认true
  • password {string} 加密压缩的密码。如果设置密码但不设置加密方法,则加密方法默认为AES
  • readHiddenFiles {boolean} 压缩文件夹时是否包含隐藏文件。如果为true,则在将文件夹添加到zip时将包含隐藏文件
  • rootFolderInZip {string} 设置压缩包首目录的文件夹名称,如果没有首目录,则创建这个首目录

解压选项

options {object} 包括:

  • ignoreAttribute {string[]} 解压文件写入磁盘时,要忽略的文件属性,包括:
    • alls 所有属性
    • archive 压缩包属性
    • dateTime 时间
    • hidden 是否隐藏
    • readOnly 是否只读
    • system 是否为系统文件

扩展

Java 读取 ZIP 文件条目

js
// 引入 Java 所需的类,用于处理文件输入和 ZIP 读取
importClass(java.io.FileInputStream);       // 文件输入流
importClass(java.io.BufferedInputStream);   // 缓冲输入流,提高读取效率
importClass(java.util.zip.ZipInputStream);  // ZIP 输入流,用于解析 ZIP 文件
importClass(java.util.zip.ZipEntry);        // ZIP 条目类,表示 ZIP 中的每个文件或目录
importClass(java.nio.charset.Charset);      // 字符编码设置

// 指定 ZIP 文件路径(可根据实际路径修改)
var path = "/sdcard/cloud/abc.zip";

// 定义输入流变量(后面用于 try-catch-finally 结构中)
var fis = null, bis = null, zis = null;

try {
    // 创建文件输入流
    fis = new FileInputStream(path);
    
    // 用缓冲流包装文件流,提高读取性能
    bis = new BufferedInputStream(fis);
    
    // 使用 GB18030 编码创建 ZipInputStream,以支持中文文件名
    zis = new ZipInputStream(bis, Charset.forName("GB18030"));

    var entry;
    // 遍历 ZIP 文件中的每个条目(文件或目录)
    while ((entry = zis.getNextEntry()) != null) {
        // 输出当前条目的名称以及是否是目录
        console.log(entry.getName() + (entry.isDirectory() ? " (Directory)" : " (File)"));
        
        // 关闭当前条目,准备读取下一个
        zis.closeEntry();
    }
} catch (e) {
    // 捕获异常并打印错误信息
    console.log("Error processing zip file: " + e);
} finally {
    // 在最终阶段关闭所有打开的流,释放资源(注意顺序)
    if (zis) zis.close();
    if (bis) bis.close();
    if (fis) fis.close();
}

🔍 说明: 使用 Charset.forName("GB18030") 是为了兼容中文命名的 ZIP 条目,避免乱码; 如果确认 ZIP 是 UTF-8 编码,也可以替换成 "UTF-8"; 可用于文件名提取、解压过滤、中文兼容验证等场景。