在 Node.js 中读取第 N 行到第 M 行的文本文件

Read from Nth to Mth line of text file in Node.js

虽然我找到了很多关于逐行读取文本文件或读取第 N 行的示例,但我找不到任何关于如何从第 N 行读取到第 M 行的内容。

文件有点大,约 5 GB(约 1000 万行)。

编辑:线条没有固定长度。

您可以使用 readline 功能将文件作为流读取,而无需将其作为一个整体加载到 RAM 中。这是如何完成的示例:

const fs = require('fs');
const readline = require('readline');

function readFromN2M(filename, n, m, func) {
  const lineReader = readline.createInterface({
    input: fs.createReadStream(filename),
  });

  let lineNumber = 0;

  lineReader.on('line', function(line) {
    lineNumber++;
    if (lineNumber >= n && lineNumber < m) {
      func(line, lineNumber);
    }
  });
}

让我们试试看:

// whatever you would like to do with those lines
const fnc = (line, number) => {
  // e.g. print them to console like this:
  console.log(`--- number: ${number}`);
  console.log(line);
};

// read from this very file, lines from 4 to 7 (excluding 7):
readFromN2M(__filename, 4, 7, fnc);

这给出了输出:

//  --- number: 4
//  function readFromN2M(filename, n, m, func) {
//  --- number: 5
//    const lineReader = readline.createInterface({
//  --- number: 6
//      input: fs.createReadStream(filename),

行从 1 开始编号。要从 0 开始,只需稍微修改编号即可。

更新:

我刚刚意识到,从某种意义上说,这种方法不是 100% 安全的,如果某些文件没有以换行字符结尾,那么这样的文件的最后一行将不会以这种方式读取。这就是 readline 的设计方式......为了克服这个问题,我以更复杂的方式准备文件流 - 通过在需要时向这些流添加新的行字符。这会使解决方案更长一些。但一切皆有可能。

更新 2

正如您在评论中提到的,即使已经找到所需的行,lineReader 仍会继续遍历,这会减慢应用程序的速度。我想我们可以这样阻止它:

lineReader.on('line', function(line) {
  lineNumber++;
  if (lineNumber >= n && lineNumber < m) {
    func(line, lineNumber);
  }

接下来的 3 行应该停止 lineReader 'soon',但不会像 official docs

中解释的那样立即停止
  if (lineNumber > m) {
    lineReader.close();
  }
});

我相信这应该可以解决问题。