运行时依赖
安装命令
点击复制技能文档
存档器 — 流式存档打包 一个支持 ZIP 和 TAR 的 Node.js 流式存档库,能够从多个数据源追加内容。
用例 当用户需要压缩和打包、创建 zip/tar 档案、打包目录或以编程方式生成压缩文件时使用。
触发词 压缩、打包、存档、zip、tar、存档、archiver。
安装 npm install archiver
快速开始:ZIP 打包
const fs = require('fs');
const archiver = require('archiver');
const output = fs.createWriteStream('output.zip');
const archive = archiver('zip', { zlib: { level: 9 } });
output.on('close', () => {
console.log(${archive.pointer()} bytes written);
});
archive.on('error', (err) => {
throw err;
});
archive.pipe(output);
// 追加 — 多个数据源
archive.append(fs.createReadStream('file.txt'), { name: 'file.txt' });
// 流
archive.append('string content', { name: 'readme.txt' });
// 字符串
archive.append(Buffer.from('data'), { name: 'data.bin' });
// Buffer
archive.file('local-file.txt', { name: 'renamed.txt' });
// 本地文件
archive.directory('src/', 'src');
// 目录 → 子目录在存档中
archive.directory('dist/', false);
// 目录内容 → 存档根目录
archive.glob('.js', { cwd: __dirname });
// Glob 匹配
archive.finalize();
数据源概述 方法 数据源 名称 参数 archive.append(stream, { name }) ReadStream 必需 archive.append(string, { name }) String 必需 archive.append(buffer, { name }) Buffer 必需 archive.file(path, { name }) 文件路径 可选,可以重命名 archive.directory(path, dest) 目录 false = 内容到根;字符串 = 子目录名称 archive.glob(pattern, { cwd }) Glob 匹配 自动使用匹配的文件名
TAR 打包 const archive = archiver('tar', { gzip: true, gzipOptions: { level: 6 } });
TAR 特定选项: 选项 描述 默认值 gzip 启用 gzip 压缩 false gzipOptions.level 压缩级别 0-9 6
事件 archive.on('warning', (err) => { if (err.code === 'ENOENT') console.warn('文件未找到:', err); else throw err; }); archive.on('error', (err) => { throw err; }); // 事件在管道目标流上(来自 Node.js Stream API) output.on('close', () => { / 文件描述符关闭 / }); output.on('end', () => { / 数据排干 / }); output.on('finish', () => { / 所有数据写入 / }); warning — 非致命错误(例如,文件未找到,stat 失败等);ENOENT 可以忽略,其他应该抛出 error — 致命错误;必须处理 close (output) — 发出在文件描述符关闭后;archive.pointer() 可以用来获取此时的总字节数 end (output) — 数据排干;无论数据源进度如何都发出 progress — 进度跟踪,请参见下面
进度跟踪
archive.on('progress', (progress) => {
console.log(${progress.entries.processed} / ${progress.entries.total} 条目);
console.log(${progress.fs.processedBytes} / ${progress.fs.totalBytes} 字节);
});
进度对象结构:
{
entries: {
total: number,
processed: number
},
fs: {
totalBytes: number,
processedBytes: number
}
}
常见模式 模式 1:响应式存档 — HTTP 流输出 app.get('/download', (req, res) => { res.attachment('archive.zip'); const archive = archiver('zip', { zlib: { level: 1 } }); // 低压缩 = 更快的存档 archive.on('error', (err) => { res.status(500).end(); }); archive.pipe(res); archive.directory('user-files/', false); archive.finalize(); });
模式 2:条件追加 — 按需打包 const archive = archiver('zip'); // 动态追加基于条件 if (includeSource) { archive.directory('src/', 'source'); } if (includeDocs) { archive.glob('docs//.md', { cwd: __dirname }); } archive.finalize();
模式 3:内存存档 — 无文件输出
const { Writable } = require('stream');
const chunks = [];
const memoryStream = new Writable({
write(chunk, enc, cb) {
chunks.push(chunk);
cb();
}
});
const archive = archiver('zip');
archive.pipe(memoryStream);
archive.append('hello', { name: 'hello.txt' });
archive.finalize();
memoryStream.on('finish', () => {
const buffer = Buffer.concat(chunks);
console.log(存档在内存中:${buffer.length} 字节);
// 可用于上传、发送等
});
模式 4:批量打包 — 多个存档串行
async function createBatchedArchives(fileGroups, outputDir) {
for (const [i, files] of fileGroups.entries()) {
await new Promise((resolve, reject) => {
const output = fs.createWriteStream(${outputDir}/batch-${i}.zip);
const archive = archiver('zip');
archive.on('error', reject);
output.on('close', resolve);
archive.pipe(output);
files.forEach(f => archive.file(f, { name: path.basename(f) }));
archive.finalize();
});
}
}