Node.js使用fflate流式压缩JSON文件报错求助
问题排查与解决方案
你的代码报错核心原因是:fflate原生的Gzip类并非Node.js标准的Transform Stream,不兼容Node.js的pipe方法。Node.js的流操作要求对象实现Stream接口,而fflate核心库的流是独立实现的,因此直接pipe会抛出类似"TypeError: dest.on is not a function"的错误。
修正方案一:使用fflate的Node.js流适配层(推荐)
fflate提供了专门适配Node.js Stream的模块fflate.node,其中的Gzip类完全兼容Node.js的Transform Stream,可以直接用pipe操作。
修正后的代码:
const fs = require('fs'); const fflate = require('fflate'); const inputFilePath = './responses/output1.json'; const outputFilePath = './responses/output1.gz'; // 读取二进制数据即可,无需设置utf8编码 const readStream = fs.createReadStream(inputFilePath); const writeStream = fs.createWriteStream(outputFilePath); // 使用fflate.node.Gzip替代原生Gzip const gzipStream = new fflate.node.Gzip({ level: 6 }); readStream.pipe(gzipStream).pipe(writeStream); // 完善错误监听,避免未捕获异常 writeStream.on('finish', () => { console.log('File compression completed.'); }); writeStream.on('error', (err) => { console.error('Error compressing file:', err); }); readStream.on('error', (err) => { console.error('Read stream error:', err); writeStream.destroy(); }); gzipStream.on('error', (err) => { console.error('Gzip stream error:', err); writeStream.destroy(); });
修正方案二:手动处理流数据(不依赖适配层)
如果不想使用适配层,可以手动监听Node.js流的data、end事件,将数据传递给fflate的Gzip实例,并处理压缩结果的写入:
const fs = require('fs'); const fflate = require('fflate'); const inputFilePath = './responses/output1.json'; const outputFilePath = './responses/output1.gz'; const readStream = fs.createReadStream(inputFilePath); const writeStream = fs.createWriteStream(outputFilePath); // 初始化Gzip,传入回调处理压缩后的数据 const gzip = new fflate.Gzip({ level: 6 }, (compressedChunk, isFinal) => { writeStream.write(compressedChunk); if (isFinal) { writeStream.end(); } }); readStream.on('data', (chunk) => { // 将读取到的二进制chunk传入Gzip gzip.push(chunk); }); readStream.on('end', () => { // 通知Gzip所有数据已传入,完成压缩 gzip.push(new Uint8Array(), true); }); // 错误处理 readStream.on('error', (err) => { console.error('Read error:', err); gzip.push(new Uint8Array(), true); writeStream.destroy(); }); writeStream.on('finish', () => { console.log('Compression completed.'); }); writeStream.on('error', (err) => { console.error('Write error:', err); });
额外注意事项
- 不要给读取流设置
encoding: 'utf8':压缩操作直接处理二进制数据效率更高,fflate可以直接接收Node.js的Buffer(内部会转换为Uint8Array)。 - 必须监听所有流的错误事件:避免因某个流出错导致程序崩溃且无日志输出。
内容的提问来源于stack exchange,提问作者Alen George
相关产品推荐
相关产品推荐

