在 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();
}
});
我相信这应该可以解决问题。
虽然我找到了很多关于逐行读取文本文件或读取第 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();
}
});
我相信这应该可以解决问题。