简体   繁体   English

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

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

I've been trying to add a use case to my code in which I try to unzip a zip that is too large to fit in the disk space and I expect my code to throw ENOSPC.我一直在尝试在我的代码中添加一个用例,在该用例中我尝试解压缩一个太大而无法放入磁盘空间的 zip,我希望我的代码会抛出 ENOSPC。 I've tried multiple libraries but none of them throw error rather fail silently without completing the zipping.我尝试了多个库,但没有一个库会抛出错误,而是在没有完成压缩的情况下静默失败。 I'd expect them to throw ENOSPC error but all the packages seem to log the first info statement which states that the unzipping has been started but nothing after that.我希望他们会抛出 ENOSPC 错误,但所有包似乎都记录了第一个 info 语句,该语句指出解压缩已经开始,但之后没有任何内容。 Most of them create incomplete folders, whatever they could write before disk went out of space.他们中的大多数人创建了不完整的文件夹,无论他们在磁盘空间不足之前可以写什么。 Here is how my code looks like for each of the libraries.这是每个库的代码的样子。

My code using adm-zip :我使用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)
    }
};

Code using yauzl :使用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();
                });
              });
            });
          }
        });
      });
    });
  }

Code using 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)
    }
};

Code Using extract-zip :使用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
      }
};

Is there something wrong with my code?我的代码有问题吗? Is there any special event that I need to listen on?有什么特别的活动我需要听吗?

After some trail and error on both Yauzl and unzipper, unzipper seemed to work (throw ENOSPC when ran out of disk space during unzipping) with the following code.在 Yauzl 和 unzipper 上都有一些跟踪和错误之后,unzipper 似乎可以使用以下代码工作(在解压缩过程中磁盘空间不足时抛出 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));
        }
    });
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM