使用archiver生成的Zip文件经fs-extra复制后损坏,是什么原因?
问题根因
- archiver的压缩、文件写入属于异步IO操作,
archive.finalize()仅触发压缩结束指令,不会等待所有内容完整写入磁盘就会返回 - 写入流在初始化时就会创建目标空文件,因此你调用
fs.existsSync(targetPath)会返回true,但此时zip的核心结构、末尾目录信息还未写入,复制得到的是不完整的损坏文件 - 后续你手动打开original.zip正常,是因为中间的时间差已经让写入流完成了全部内容落盘
修复方案
监听写入流的close事件,确认压缩包完全写入完成后再执行复制操作,修正后代码如下:
const fs = require("fs-extra"); const archiver = require("archiver"); const targetPath = __dirname + "/original.zip" const output = fs.createWriteStream(targetPath); const archive = archiver("zip", { zlib: { level: 9 }, // 压缩等级 }); archive.pipe(output); archive.append("string cheese!", { name: "file2.txt" }); // 写入流完成回调,此时压缩包已完整生成 output.on('close', () => { if (fs.existsSync(targetPath)) { fs.copySync(targetPath, "copied.zip", { overwrite: true }); } }); // 可选:添加错误监听处理异常 output.on('error', (err) => { console.error('压缩出错:', err); }); archive.finalize();
内容的提问来源于stack exchange,提问作者ddeark
相关产品推荐
相关产品推荐

