Node.js无需解压将.gz文件读取到数组的实现方法
在Node.js中无需解压读取.gz文件到数组的实现方法
问题分析
你当前代码的核心问题是异步执行顺序:console.log(myarray)是同步执行的,而lineReader的line事件是异步触发的,所以打印时数组还未被填充。此外,数组赋值的方式myarray[n]=line可以简化为myarray.push(line),写法更简洁。
解决方案
方案1:传统事件监听(兼容所有Node.js版本)
通过监听close事件,确保所有行读取完成后再处理数组,适合大文件(逐行读取,内存占用低):
const fs = require('fs'); const zlib = require('zlib'); const readline = require('readline'); const lineReader = readline.createInterface({ input: fs.createReadStream('myfile.gz').pipe(zlib.createGunzip()) }); const myarray = []; lineReader.on('line', (line) => { myarray.push(line); console.log(`line: ${myarray.length}`); console.log(line); }); lineReader.on('close', () => { // 所有行读取完成,此时数组已填充完整 console.log(myarray); // 在这里执行后续逻辑 });
方案2:Promise + async/await(现代简洁写法)
利用readline/promises模块(Node.js 16.14.0+ 或 17.0.0+ 支持),用异步函数同步化流程,代码可读性更高:
const fs = require('fs'); const zlib = require('zlib'); const { createInterface } = require('readline/promises'); async function readGzFileToArray(filePath) { const myarray = []; const lineReader = createInterface({ input: fs.createReadStream(filePath).pipe(zlib.createGunzip()), crlfDelay: Infinity // 兼容不同系统的换行符 }); for await (const line of lineReader) { myarray.push(line); console.log(`line: ${myarray.length}`); console.log(line); } return myarray; } // 调用示例 readGzFileToArray('myfile.gz') .then(array => { console.log(array); // 后续处理逻辑 }) .catch(err => { console.error('读取文件出错:', err); });
方案3:一次性读取(适合小文件)
如果文件体积较小,可以直接将解压后的流转换为字符串,再按行分割,代码更简单:
const fs = require('fs'); const zlib = require('zlib'); function readGzFileToArray(filePath) { return new Promise((resolve, reject) => { const chunks = []; fs.createReadStream(filePath) .pipe(zlib.createGunzip()) .on('data', chunk => chunks.push(chunk)) .on('end', () => { const content = Buffer.concat(chunks).toString(); // 过滤空行,可根据需求调整 const myarray = content.split('\n').filter(line => line.trim() !== ''); resolve(myarray); }) .on('error', err => reject(err)); }); } // 调用示例 readGzFileToArray('myfile.gz') .then(array => console.log(array)) .catch(err => console.error(err));
方案对比
- 方案1:兼容所有Node.js版本,逐行读取内存占用低,适合处理大文件。
- 方案2:代码结构清晰易读,异步流程更直观,需要较高版本Node.js支持。
- 方案3:实现简单,但一次性读取会占用较多内存,仅适合小体积文件。
内容的提问来源于stack exchange,提问作者user3152377
相关产品推荐
相关产品推荐

