我想压缩一个文件夹,然后我必须在 Gulp 任务中删除它。 我正在尝试以同步方式使用archiver。
我使用归档器的 npm 页面中的快速入门指南中的代码,它成功创建了 zip 文件。
但是如果我也尝试删除压缩文件夹,则存档器没有足够的时间来创建 zip。
const output = fs.createWriteStream(__dirname + '/example.zip');
//
// code as in https://www.npmjs.com/package/archiver
// ...
archive.finalize();
execSync(
`rm -rf ${config.paths.dest}`,
);
现在我切换到 zip-local 包,它以同步方式工作,所以我“解决”了问题,但现在我被迫压缩整个文件夹,而不是选择特定的文件和文件夹,并且输出 zip 太多更大。
我不是专家,我确信这是由于我对存档器工作原理的理解有限而导致的问题。
有人可以帮助我吗?
使用存档器,我成功地完成了我想要的操作,删除了“关闭”事件中的文件夹:
output.on('close', function () {
console.log(`Zip created`);
execSync(
`rm -rf ${config.paths.dest}`,
);
});
但我不太喜欢这个解决方案。
我尝试使用承诺并观看了很多视频,但这是一个无法留在我大脑中的概念,我有点沮丧。
最好的方法是使用 Promise (PromiseAll) 这是例子
const promise = new Promise((resolve, reject) => {
let dir = "./compress-files";
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
dir = `./compress-files/${sub}.zip`;
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
const password = Math.random().toString(36).slice(-8);
var output = fs.createWriteStream(dir);
var archive = archiver("zip-encryptable", {
zlib: { level: 9 },
forceLocalTime: true,
password: password,
});
console.log("password", password);
output.on("close", function () {
console.log(archive.pointer() + " total bytes");
resolve(dir);
});
archive.on("error", function (err) {
throw err;
reject(false);
});
// pipe archive data to the output file
archive.pipe(output);
// append files
archive.directory(`./excel-files/${sub}`, false);
archive.finalize();
console.log("zipped");
});
Promise.all([promise]).then(async (values) => {
console.log("finally", values); /// perform action here
});
我不知道这对你是否有帮助,但我发现 2016/11/23 的 archiver-promise 将 archiver 包装在一个承诺中。
我也不是
async
/await
或 promises
方面的专家,所以我的代码可能不是最好的实现。但它允许我包装存档器以返回我可以在继续下一步之前观看的承诺。
发布在这里供其他人验证。我真的更喜欢
async
/await
实现。
在我将例程包装在承诺中之前,归档的总字节数报告会在下一个操作开始后显示。
Preparing archive: ../archives/example-archive.zip
Trigger next action
291302 total bytes
now we can work
将例程包装在承诺中后,在触发下一个操作之前会显示已归档的总字节数报告。
Preparing archive: ../archives/example-archive.zip
291302 total bytes
now we can work
Trigger next action
const fs = require('fs-extra')
const archiver = require('archiver-promise')
/**
* Creates an archive of a folder of files. Could be modified to
* archive specific files from the source folder.
* @param {string} source_path - Full path to source folder
* @param {string} archive_filename - Full path to archive name. Must end with `.zip`
*/
const archive_folder = (source_path, archive_filename) => {
return new Promise((resolve, reject) => {
console.log(`Preparing archive: ${archive_filename}`)
const archive = archiver(archive_filename, {
store: true
})
archive.directory(source_path)
archive.finalize()
.then(() => {
console.log(`${archive.pointer()} total bytes`)
// Resolve with a status object.
resolve('now we can work')
})
.catch((err) => {
reject(err)
})
})
}
// Calling routine
archive_folder('../example/source/folder', '../archives/example-archive.zip')
.then((response) => {
console.log(response)
})
.then(() => {
console.log('Trigger next action')
// continue next actions...
})
.catch((err) => {
console.error(err)
})
/**
* Creates an archive of a folder of files without promises.
* @param {string} source_path - Full path to source folder
* @param {string} archive_filename - Full path to archive name. Must end with `.zip`
*/
const archive_folder_np = (source_path, archive_filename) => {
console.log(`Preparing archive: ${archive_filename}`)
const archive = archiver(archive_filename, {
store: true
})
archive.directory(source_path)
archive.finalize()
.then(() => {
console.log(`${archive.pointer()} total bytes`)
console.log('now we can work')
})
.catch((err) => {
console.error(err)
})
}
// Calling routine
archive_folder_np('../example/source/folder', '../archives/example-archive.zip')
console.log('Trigger next action')