I want to keep the fs
read stream open and read n number of lines at a time whenever I want manually. I don't want to hook up the on() event handler with 'data' as it makes the stream to continuously read automatically until the end. There is no telling how long it would take before it's manually triggered to read the next set of lines are read.
CodePudding user response:
I've made a short function which should do what you want
const { createReadStream } = require('fs');
// wrapping everything in async function so await can be used
// not needed when global await is available
(async () => {
// create readable stream
const stream = createReadStream('lorem.txt', { encoding: 'utf-8' })
// get readLine function instance
const { readLine } = await createReader(stream)
// read 100 lines, you can read as many as you want
// don't have to read all at once
for (let i = 0; i < 100; i = 1) {
console.log(readLine())
}
// readLine factory
async function createReader(stream) {
// current bytes
let bytes = ''
// await for stream to load and be readable
await new Promise(r => stream.once('readable', r))
// return readLine function
return {
readLine() {
let index
// while there is no new line symbol in current bytes
while ((index = bytes.indexOf('\n')) === -1) {
// read some data from stream
const data = stream.read()
// if data is null it means that the file ended
if (data === null) {
// if no bytes left just return null
if (!bytes) return null
// if there are some bytes left return them and clear bytes
const rest = bytes
bytes = ''
return rest
}
bytes = data
}
// get characters till new line
const line = bytes.slice(0, index)
// remove first line from current bytes
bytes = bytes.slice(index 1)
// return the first line
return line
}
}
}
})()