Node.js提供了多种文件压缩的实现方式,开发者可以根据实际需求选择内置模块或者第三方库来完成压缩操作,不同的方案适用场景有所区别。

使用内置zlib模块压缩单个文件
Node.js内置的zlib模块提供了多种压缩算法,最常用的就是gzip压缩,适合处理单个文件的压缩需求,不需要额外安装依赖。
基础压缩实现
我们可以通过流的方式读取文件内容,经过zlib压缩后写入新的压缩文件,代码如下:
const fs = require('fs');
const zlib = require('zlib');
// 创建读取流和写入流
const readStream = fs.createReadStream('./test.txt');
const writeStream = fs.createWriteStream('./test.txt.gz');
// 创建gzip压缩流
const gzip = zlib.createGzip();
// 管道连接:读取文件 -> 压缩 -> 写入压缩文件
readStream.pipe(gzip).pipe(writeStream);
writeStream.on('finish', () => {
console.log('单文件压缩完成');
});压缩参数配置
zlib的压缩方法支持传入配置参数,比如调整压缩级别,平衡压缩速度和压缩率:
const fs = require('fs');
const zlib = require('zlib');
const readStream = fs.createReadStream('./test.txt');
const writeStream = fs.createWriteStream('./test_high.txt.gz');
// 设置压缩级别为9,最高压缩率,速度较慢
const gzip = zlib.createGzip({ level: 9 });
readStream.pipe(gzip).pipe(writeStream);使用archiver库打包压缩多个文件
如果需要压缩多个文件或者整个目录,内置的zlib模块就不够用了,这时候可以使用第三方库archiver,它支持zip、tar等多种压缩格式,还能自定义压缩规则。
安装依赖
首先需要通过npm安装archiver:
npm install archiver
多文件压缩实现
下面的代码演示了如何把指定目录下的所有文件打包成zip压缩包:
const fs = require('fs');
const archiver = require('archiver');
// 创建输出流,写入最终的zip文件
const output = fs.createWriteStream('./dist.zip');
const archive = archiver('zip', {
zlib: { level: 9 } // 设置zip压缩级别
});
// 监听输出流完成事件
output.on('close', () => {
console.log('压缩包生成完成,大小:' + archive.pointer() + '字节');
});
// 监听错误事件
archive.on('error', (err) => {
throw err;
});
// 把输出流和archiver关联
archive.pipe(output);
// 添加单个文件到压缩包
archive.file('./test.txt', { name: 'test.txt' });
// 添加整个目录到压缩包,会保留目录结构
archive.directory('./src/', 'src');
// 完成压缩
archive.finalize();两种方案对比
我们可以根据实际需求选择合适的压缩方案,两者的区别如下:
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| zlib内置模块 | 单个文件压缩,简单压缩需求 | 无需额外安装依赖,轻量高效 | 不支持多文件打包,格式仅支持gzip等基础类型 |
| archiver库 | 多文件/目录打包,复杂压缩需求 | 支持多种压缩格式,可自定义打包规则 | 需要额外安装依赖,体积稍大 |
注意事项
- 压缩大文件时建议使用流的方式处理,避免一次性读取全部内容到内存导致内存溢出
- 压缩级别越高,压缩率越好但耗时越长,需要根据实际需求平衡
- 使用archiver添加目录时,注意路径权限问题,避免因为权限不足导致文件添加失败
- 压缩完成后要正确监听流的finish或者close事件,确保文件写入完成再执行后续操作
如果压缩过程中遇到文件编码问题,可以在读取文件流的时候指定encoding参数,确保文件内容正确读取后再进行压缩。