1

我一直在尝试在我的代码中添加一个用例,在该用例中我尝试解压缩一个太大而无法放入磁盘空间的 zip,并且我希望我的代码会抛出 ENOSPC。我已经尝试了多个库,但它们都没有抛出错误,而是在没有完成压缩的情况下静默失败。我希望他们会抛出 ENOSPC 错误,但所有包似乎都记录了第一个 info 语句,该语句指出解压缩已经开始,但之后没有任何内容。他们中的大多数人创建了不完整的文件夹,无论他们在磁盘空间不足之前可以写什么。这是每个库的代码的样子。

我使用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();
                });
              });
            });
          }
        });
      });
    });
  }

使用解压缩的代码:

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
      }
};

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

4

1 回答 1

0

在 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));
        }
    });
};
于 2020-04-28T16:53:42.763 回答