You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:45:33