Node.js "readline" + "fs. createReadStream" : 指定开始和结束行号
Node.js "readline" + "fs. createReadStream" : Specify start & end line number
https://nodejs.org/api/readline.html
提供此解决方案以逐行读取 CSV 等大文件:
const { createReadStream } = require('fs');
const { createInterface } = require('readline');
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();
但我不想从头到尾阅读整个文件,但它的部分内容是从行号 1 到 10000、20000 到 30000 等。
基本上我希望能够为我的函数的给定 运行 设置 'start' & 'end' 行。
这对 readline
和 fs.createReadStream
可行吗?
如果不是,请提出替代方法。
PS: 这是一个大文件(大约 1 GB)并且将其加载到内存中会导致内存问题。
换行只是一个字符(如果您在 windows 上,则为两个字符),如果不处理文件,您无法知道这些字符的位置。
但是您只能读取文件中的特定字节范围。如果您知道每行包含 64 个字节这一事实,则可以通过从字节 6400 开始读取来跳过前 100 行,并且可以通过在字节 12800 停止读取来仅读取 100 行。
有关如何指定起点和终点的详细信息,请参阅 createReadStream
文档。
But I don't want to read the entire file from beginning to end but parts of it say from line number 1 to 10000, 20000 to 30000, etc.
除非您的行是固定的、相同的长度,否则如果不从文件开头读取并计算行数直到到达第 10,000 行,就无法知道第 10,000 行从何处开始。这就是具有可变长度行的文本文件的工作方式。文件中的行不是文件系统知道的物理结构。对于文件系统,文件只是一个巨大的数据块。行的概念是我们在更高层次上发明的,因此文件系统或 OS 对行一无所知。知道行在哪里的唯一方法是读取数据并通过搜索行定界符将其“解析”为行。所以,第10,000行只能通过搜索从文件开头开始的第10,000行分隔符并计数来找到。
没有办法解决它,除非您将文件预处理为更有效的格式(如数据库)或创建行位置索引。
Basically I want to be able to set a 'start' & 'end' line for a given run of my function.
唯一的方法是提前“索引”数据,这样您就已经知道每一行的位置 starts/ends。一些用来处理非常大的文件的文本编辑器就是这样做的。他们通读文件(可能是懒惰地)读取每一行,并建立一个内存索引,记录每行开始的文件偏移量。然后,他们可以通过查询索引并从文件中读取该组数据来检索特定的行块。
Is this doable with readline & fs.createReadStream?
没有固定长度的行,如果不从头开始计数,就无法知道文件中的第 10,000 行从哪里开始。
It's a large file(around 1 GB) & loading it in memory causes MEMORY ISSUES.
使用 linereader 模块或其他执行类似操作的模块一次流式传输文件将很好地处理内存问题,以便在任何给定时间内存中只有文件中的数据块。即使在小内存系统中,您也可以通过这种方式处理任意大文件。
https://nodejs.org/api/readline.html
提供此解决方案以逐行读取 CSV 等大文件:
const { createReadStream } = require('fs');
const { createInterface } = require('readline');
(async function processLineByLine() {
try {
const rl = createInterface({
input: createReadStream('big-file.txt'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
// Process the line.
});
await once(rl, 'close');
console.log('File processed.');
} catch (err) {
console.error(err);
}
})();
但我不想从头到尾阅读整个文件,但它的部分内容是从行号 1 到 10000、20000 到 30000 等。
基本上我希望能够为我的函数的给定 运行 设置 'start' & 'end' 行。
这对 readline
和 fs.createReadStream
可行吗?
如果不是,请提出替代方法。
PS: 这是一个大文件(大约 1 GB)并且将其加载到内存中会导致内存问题。
换行只是一个字符(如果您在 windows 上,则为两个字符),如果不处理文件,您无法知道这些字符的位置。
但是您只能读取文件中的特定字节范围。如果您知道每行包含 64 个字节这一事实,则可以通过从字节 6400 开始读取来跳过前 100 行,并且可以通过在字节 12800 停止读取来仅读取 100 行。
有关如何指定起点和终点的详细信息,请参阅 createReadStream
文档。
But I don't want to read the entire file from beginning to end but parts of it say from line number 1 to 10000, 20000 to 30000, etc.
除非您的行是固定的、相同的长度,否则如果不从文件开头读取并计算行数直到到达第 10,000 行,就无法知道第 10,000 行从何处开始。这就是具有可变长度行的文本文件的工作方式。文件中的行不是文件系统知道的物理结构。对于文件系统,文件只是一个巨大的数据块。行的概念是我们在更高层次上发明的,因此文件系统或 OS 对行一无所知。知道行在哪里的唯一方法是读取数据并通过搜索行定界符将其“解析”为行。所以,第10,000行只能通过搜索从文件开头开始的第10,000行分隔符并计数来找到。
没有办法解决它,除非您将文件预处理为更有效的格式(如数据库)或创建行位置索引。
Basically I want to be able to set a 'start' & 'end' line for a given run of my function.
唯一的方法是提前“索引”数据,这样您就已经知道每一行的位置 starts/ends。一些用来处理非常大的文件的文本编辑器就是这样做的。他们通读文件(可能是懒惰地)读取每一行,并建立一个内存索引,记录每行开始的文件偏移量。然后,他们可以通过查询索引并从文件中读取该组数据来检索特定的行块。
Is this doable with readline & fs.createReadStream?
没有固定长度的行,如果不从头开始计数,就无法知道文件中的第 10,000 行从哪里开始。
It's a large file(around 1 GB) & loading it in memory causes MEMORY ISSUES.
使用 linereader 模块或其他执行类似操作的模块一次流式传输文件将很好地处理内存问题,以便在任何给定时间内存中只有文件中的数据块。即使在小内存系统中,您也可以通过这种方式处理任意大文件。