使用 adm-zip/unzipper/yauzl 解压缩在节点 10 中静默失败

Unzip using adm-zip/unzipper/yauzl fails in node 10 silently

我一直在尝试向我的代码添加一个用例,在该用例中我尝试解压缩一个太大而无法放入磁盘的 zip space,我希望我的代码抛出 ENOSPC。我已经尝试了多个库,但其中 none 个库会抛出错误,而不会在没有完成压缩的情况下默默地失败。我希望他们抛出 ENOSPC 错误,但所有的包似乎都记录了第一个信息声明,该声明声明解压缩已经开始,但之后什么也没有。他们中的大多数创建了不完整的文件夹,无论他们在磁盘用完 space 之前可以写入什么。这是我的代码对于每个库的样子。

我的代码使用 adm-zip:

exports.unzip = function(source, destination) {
    console.info("Started un-zipping from source: %s to destination: %s", source, destination);
    try {
        const zip = new AdmZip(source);
        zip.extractAllTo(destination, true);
        console.info("done unzipping");
    } catch (error) {
        console.error("Unzipping failed. Reason: %s", error)
        throw new Error(error)
    }
};

代码使用 yauzl:

exports.extractZip = function(source, destination) {
    return new Promise(function(resolve, reject) {
      console.log("Extracting zip: '" + source + "' to '" + destination + "'");

      yauzl.open(source, {
        lazyEntries: true
      }, function(err, zipfile) {
        if (err) throw err;
        zipfile.readEntry();
        zipfile.on("error", function (err) {
            console.error("Something went wrong while extracting!");
            reject(new Error(err));
        });
        zipfile.on("end", function () {
            console.log("Completed extracting zip!");
            resolve();
        });
        zipfile.on("entry", function(entry) {
          if (/\/$/.test(entry.fileName)) {
            // directory file names end with '/'
            mkdirp(destination + '/' + entry.fileName, function(err) {
              if (err) {
                  console.error("Something went wrong while extracting!");
                  throw err;
              }
              zipfile.readEntry();
            });
          } else {
            // file entry
            zipfile.openReadStream(entry, function(err, readStream) {
              if (err) {
                console.error("Something went wrong while extracting!");
                throw err;
              }
              // ensure parent directory exists
              mkdirp(destination + '/' + path.dirname(entry.fileName), function(err) {
                if (err) throw err;
                readStream.pipe(fs.createWriteStream(destination + '/' + entry.fileName));
                readStream.on("end", function() {
                  zipfile.readEntry();
                });
              });
            });
          }
        });
      });
    });
  }

代码使用 Unzipper:

exports.unzip2 = function(source, destination) {
    console.info("Started un-zipping from source: %s to destination: %s", source, destination);
    try {
        fs.createReadStream(source)
        .pipe(unzipper.Extract({ path: destination }))
        .on('error',function (err){
            console.error("something went wrong", err.code);
            throw err;
        });
    } catch (error) {
        console.error("Unzipping failed. Reason: %s", error)
        throw new Error(error)
    }
};

代码使用 extract-zip:

exports.extractArchive = async function(source, destination) {
    try {
        extract(source, { dir: destination }, function (err) {
            if (err) {
                console.error("Something went wrong!", err.code);
                throw err;
            }
        });
        console.log('Extraction complete')
      } catch (err) {
        // handle any errors
      }
};

我的代码有问题吗?有没有我需要收听的特别活动?

在 Yauzl 和解压缩器上进行了一些尝试和错误之后,解压缩器似乎可以使用以下代码工作(当 运行 在解压缩过程中 space 磁盘外 space 时抛出 ENOSPC)。

exports.unzip2 = function(source, destination) {
    return new Promise(function(resolve, reject) {
        console.info("Started un-zipping from source: %s to destination: %s", source, destination);
        try {
            var sourceStream = fs.createReadStream(source);
            sourceStream.on('error',function (err){
                console.error("something went wrong", err.code);
                reject(new Error(err));
            });
            var destinationStream = unzipper.Extract({ path: destination });
            destinationStream.on('error',function (err){
                console.error("something went wrong", err.code);
                reject(new Error(err));
            });
            destinationStream.on('close',function (){
                console.log("Completed extract!");
                resolve();
            });
            sourceStream.pipe(destinationStream).on('error',function (err){
                console.error("something went wrong", err.code);
                reject(new Error(err));
            });;
        } catch (error) {
            console.error("something went wrong", err.code);
            reject(new Error(err));
        }
    });
};