Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

readline doesn't stop line reading after rl.close() emit in nodejs

I have the following file I want to read line by line and stop reading it once I have found "nameserver 8.8.8.8".

nameserver 8.8.8.8
nameserver 45.65.85.3
nameserver 40.98.3.3

I am using nodejs and the readline module to do so

const readline = require('readline');
const fs = require('fs');

function check_resolv_nameserver(){
  // flag indicates whether namerserver_line was found or not
  var nameserver_flag = false;

  const rl = readline.createInterface({
    input: fs.createReadStream('file_to_read.conf')
  });

  rl.on('line', (line) => {
    console.log(`Line from file: ${line}`);
    if (line === 'nameserver 8.8.8.8'){
      console.log('Found the right file. Reading lines should stop here.');
      nameserver_flag = true;
      rl.close();
    }
  });

  rl.on('close', function(){
    if (nameserver_flag === true){
      console.log('Found nameserver 8.8.8.8');
    }
    else {
      console.log('Could not find nameserver 8.8.8.8');
    }
  });
}

check_resolv_nameserver();

Since I emit a close event with rl.close() as soon as I read the first match, I would expect my Code to read only the first line and then stop reading further. But instead my output looks like this

Line from file: nameserver 8.8.8.8
Found the right file. Reading lines should stop here.
Found nameserver 8.8.8.8
Line from file: nameserver 45.65.85.3
Line from file: nameserver 40.98.3.3

How can I make readline stop after first match and let me proceed with a something else?

like image 875
gvoigt Avatar asked May 24 '17 08:05

gvoigt


People also ask

What is createInterface in node JS?

createInterface( process. stdin, process. stdout); The method createInterface() takes two parameters – the input stream and output stream – to create a readline interface.

What does readline () do in JavaScript?

The Readline module provides a way of reading a datastream, one line at a time.

How do I read the first line of a file in node JS?

In all current versions of Node. js, readline. createInterface can be used as an async iterable, to read a file line by line - or just for the first line.

How use readline module in node JS?

To use the module, you need to import it to your JavaScript file as follows: const readline = require('readline'); Next, you need to write the code for receiving user input or reading file content, depending on your requirement.


2 Answers

for those of you who can't make the linereader stop, do this (in your readline callback):

lineReader.close()
lineReader.removeAllListeners()
like image 184
Oz Shabat Avatar answered Sep 21 '22 15:09

Oz Shabat


It appears readline buffers some lines, so you'll have to add your own check.

Example:

#! /usr/bin/node

const fs = require('fs')
const readline = require('readline')

const reader = readline.createInterface({
    input: fs.createReadStream('test.js')
})

let wasRead = false

reader.on('line', line => {
    if (wasRead) return undefined
    console.log('hello world')
    wasRead = true
    reader.close()
})
like image 29
Breck Avatar answered Sep 19 '22 15:09

Breck