虽然我找到了很多逐行读取文本文件或读取第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);
}
接下来的三行代码应该会“很快”地停止lineReader,但正如官方文档中所解释的那样,不会立即停止。
if (lineNumber > m) {
lineReader.close();
}
});
func = () => {}
,看看是否仍然很慢... - Hero Qu