我不知道该怎么做。我应该从哪里开始?我已经在谷歌上搜索了,但是没有查到如何从文本文件中提取随机行的结果。
我唯一找到的是https://github.com/chrisinajar/node-rand-line,但它无法使用。我该如何读取文本文件中的随机行?
我不知道该怎么做。我应该从哪里开始?我已经在谷歌上搜索了,但是没有查到如何从文本文件中提取随机行的结果。
我唯一找到的是https://github.com/chrisinajar/node-rand-line,但它无法使用。我该如何读取文本文件中的随机行?
你可能想要查看node.js标准库函数读取文件的相关内容,fs.readFile,最终得到以下类似代码:
const fs = require("fs");
// note this will be async
function getRandomLine(filename, callback){
fs.readFile(filename, "utf-8", function(err, data){
if(err) {
throw err;
}
// note: this assumes `data` is a string - you may need
// to coerce it - see the comments for an approach
var lines = data.split('\n');
// choose one of the lines...
var line = lines[Math.floor(Math.random()*lines.length)]
// invoke the callback with our line
callback(line);
})
}
如果无法读取整个文件并进行分割,则可以参考这个Stack Overflow上的建议。
data.split is not a function
。根据这个问题的答案,我添加了 data+=''
,然后它就可以工作了。 - Teleporting Goatfoo\nbar\n
,该函数将返回其中之一:'foo'
、'bar'
或 ''
。通过更改 data.split('\n')
为 data.replace(/\n$/, '').split('\n')
来修复此问题。 - tuomassalo我有一个类似的需求,需要从一个超过100MB的文件中随机选择一行。
因此我想避免将整个文件内容存储在内存中。
最终我采用了两次迭代所有行的方法:第一次获取行数,第二次获取目标行内容。
以下是代码示例:
const readline = require('readline');
const fs = require('fs');
const FILE_PATH = 'data.ndjson';
module.exports = async () =>
{
const linesCount = await getLinesCount();
const randomLineIndex = Math.floor(Math.random() * linesCount);
const content = await getLineContent(randomLineIndex);
return content;
};
//
// HELPERS
//
function getLineReader()
{
return readline.createInterface({
input: fs.createReadStream(FILE_PATH)
});
}
async function getLinesCount()
{
return new Promise(resolve =>
{
let counter = 0;
getLineReader()
.on('line', function (line)
{
counter++;
})
.on('close', () =>
{
resolve(counter);
});
});
}
async function getLineContent(index)
{
return new Promise(resolve =>
{
let counter = 0;
getLineReader().on('line', function (line)
{
if (counter === index)
{
resolve(line);
}
counter++;
});
});
}
我可以给你一个建议,因为我没有任何演示代码
buffered reader
逐行读取文件int returnRandom(arraySize)
0
到 arraySize
之间的随机数const path = require('path')
const fs = require('fs/promises')
const FILE_NAME = path.resolve(__dirname, '../bigfile.txt')
const DELIMITER = '\n'
const READ_BUFFER_SIZE = 1000 // Must be greater than the record size
/*
* Reading a random line from a very large (does not fit in RAM) file
*
* Note that you will never get the first or last line in the file,
* but who cares when the file contains millions of lines.
*/
async function main() {
const stats = await fs.stat(FILE_NAME)
const handle = await fs.open(FILE_NAME, 'r')
for (;;) {
const randomPos = Math.floor(Math.random() * stats.size)
const buffer = Buffer.alloc(READ_BUFFER_SIZE)
await handle.read(buffer, 0, READ_BUFFER_SIZE, randomPos)
const xs = buffer.toString().split(DELIMITER)
if (xs[2] !== undefined) {
console.log('Random line:', xs[1])
}
}
}
main().catch(console.log)