使用 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));
}
});
};
我一直在尝试向我的代码添加一个用例,在该用例中我尝试解压缩一个太大而无法放入磁盘的 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));
}
});
};