内部有嵌套文件夹的 Zip 存档无法使用 yauzl 解压

KoG*_*KoG 6 javascript unzip dropbox-api yauzl

我正在编写一个软件,其中包括使用 Dropbox API 下载 zip 存档,然后使用 yauzl 解压该存档。

从数据库存储和下载文件的方式通常会产生嵌套文件夹,我需要保持这种方式。

然而,我的 yauzl 实现无法在保留嵌套文件夹结构的同时解压缩,如果存档中有嵌套文件夹,它根本不会解压缩。

这是我的解压函数,它是默认的 yauzl 示例,最后添加了本地文件写入。

const unzip = () => {
    let zipPath = "pathToFile.zip"
    let extractPath = "pathToExtractLocation"

        yauzl.open(zipPath, {lazyEntries: true}, function(err, zipfile) {
            if (err) throw err;
            zipfile.readEntry();
            zipfile.on("entry", function(entry) {
            if (/\/$/.test(entry.fileName)) {
                // Directory file names end with '/'.
                // Note that entries for directories themselves are optional.
                // An entry's fileName implicitly requires its parent directories to exist.
                zipfile.readEntry();
            } else {
                // file entry
                zipfile.openReadStream(entry, function(err, readStream) {
                if (err) throw err;
                readStream.on("end", function() {
                    zipfile.readEntry();
                });
                const writer = fs.createWriteStream(path.join(extractPath, entry.fileName));
                readStream.pipe(writer);
                });
            }
            });
        });
}
Run Code Online (Sandbox Code Playgroud)

删除该if (/\/$/.test(entry.fileName))复选框会将顶级文件夹视为文件,以不带文件扩展名且大小为 0kb 的方式提取该文件夹。我想要它做的是提取包括子文件夹在内的存档(至少深度为 2,要意识到 zip 轰炸的风险)。

使用 yauzl 可以吗?

Hug*_*ood 4

该代码需要在提取路径中创建目录树。您可以使用fs.mkdirrecursive选项来确保在提取目录之前存在该目录。

if (/\/$/.test(entry.fileName)) {
  // Directory file names end with '/'.
  // Note that entries for directories themselves are optional.
  // An entry's fileName implicitly requires its parent directories to exist.
  zipfile.readEntry();
} else {
  // file entry
  fs.mkdir(
    path.join(extractPath, path.dirname(entry.fileName)),
    { recursive: true },
    (err) => {
      if (err) throw err;
      zipfile.openReadStream(entry, function (err, readStream) {
        if (err) throw err;
        readStream.on("end", function () {
          zipfile.readEntry();
        });
        const writer = fs.createWriteStream(
          path.join(extractPath, entry.fileName)
        );
        readStream.pipe(writer);
      });
    }
  );
}
Run Code Online (Sandbox Code Playgroud)