使用node-archiver压缩目录报错:file data stream has unexpected number of bytes
解决node-archiver压缩目录时出现的"file data stream has unexpected number of bytes"错误
先修复代码里的明显错误
你的函数里有个变量引用错误,这是必须先解决的:
// 错误代码:用了未定义的options对象 const stat = fs.statSync(options.inputDirPath); // 替换为函数传入的参数inputDirPath const stat = fs.statSync(inputDirPath);
这个错误会导致路径获取异常,非调试模式下可能直接触发后续错误,调试模式下可能因环境因素暂时隐藏,但不修复会留下隐患。
针对"unexpected number of bytes"错误的解决方案
这个错误一般由以下几种情况导致,对应处理方式如下:
1. 压缩时目录内容被修改
如果压缩过程中,目标目录里的文件被其他进程写入、删除或修改,会导致流读取的字节数和预期不符。解决办法是确保压缩期间目录内容稳定,比如给目录加临时锁,或者避开文件写入的时间段执行压缩。
2. 流事件处理不完整
原代码只监听了close事件,建议补充finish事件和输出流的错误监听,确保流完整写入:
// 调整输出流的事件监听 output.on('finish', () => { resolve(); }); output.on('error', (err) => { reject(err); });
同时要注意,不要在archive.finalize()后立刻结束进程,必须等待流事件触发后再完成后续操作。
3. 依赖版本兼容性问题
这个错误在旧版本的yazl(archiver的依赖库)中偶发,执行命令更新依赖即可:
npm update archiver
4. 改用异步stat检查(避免竞态条件)
同步的fs.statSync在某些场景下可能引发竞态问题,换成异步版本更稳妥:
// 替换原同步stat代码 fs.stat(inputDirPath, (err, stat) => { if (err) { reject(err); return; } if (stat.isDirectory()) { archive.directory(inputDirPath, false); archive.finalize(); } else { reject(`${inputDirPath} is not a directory`); } });
修复后的完整代码
import archiver from "archiver"; import fs from "fs"; async function compressDirToZip(inputDirPath:string, outputFilePath:string) { return new Promise<void>((resolve, reject) => { const output = fs.createWriteStream(outputFilePath); const archive = archiver('zip', { zlib: { level: 9 } }); // 处理输出流自身的错误 output.on('error', (err) => { reject(err); }); // 流写入完成时resolve output.on('finish', () => { resolve(); }); archive.on('warning', warning => { console.warn(warning); }); archive.on('error', error => { reject(error); }); archive.pipe(output); // 异步检查目标路径是否为目录 fs.stat(inputDirPath, (err, stat) => { if (err) { reject(err); return; } if (stat.isDirectory()) { archive.directory(inputDirPath, false); archive.finalize(); } else { reject(`${inputDirPath} is not a directory`); } }); }); }
内容的提问来源于stack exchange,提问作者Mice Nic
相关产品推荐
相关产品推荐

