Home > Back-end >  Read from Node fs read stream n number of lines at a time
Read from Node fs read stream n number of lines at a time

Time:01-04

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
      }
    }
  }
})()
  • Related