【发布时间】:2019-12-06 10:57:09
【问题描述】:
虽然我找到了很多关于逐行读取文本文件或读取第 N 行的示例,但我找不到任何关于如何从第 N 行读取到第 M 行的示例。
文件有点大,约 5 GB(约 1000 万行)。
编辑:线条没有固定长度。
【问题讨论】:
虽然我找到了很多关于逐行读取文本文件或读取第 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,但不会立即停止,如 official docs 中所述
if (lineNumber > m) {
lineReader.close();
}
});
我相信这应该可以解决问题。
【讨论】:
func = () => {},看看它是否仍然很慢......