Asynchronous line-by-line file reader for node.js
Asynchronous, buffered, line-by-line file/stream reader with support for user-defined line separators.
npm install line-reader
The
eachLinefunction reads each line of the given file. Upon each new line, the given callback function is called with two parameters: the line read and a boolean value specifying whether the line read was the last line of the file. If the callback returns
false, reading will stop and the file will be closed.
var lineReader = require('line-reader');lineReader.eachLine('file.txt', function(line, last) { console.log(line);
if (/* done */) { return false; // stop reading } });
eachLinecan also be used in an asynchronous manner by providing a third callback parameter like so:
var lineReader = require('line-reader');lineReader.eachLine('file.txt', function(line, last, cb) { console.log(line);
if (/* done */) { cb(false); // stop reading } else { cb(); } });
You can provide an optional second node-style callback that will be called with
(err)on failure or
()when finished (even if you manually terminate iteration by returning
falsefrom the iteratee):
var lineReader = require('line-reader');// read all lines: lineReader.eachLine('file.txt', function(line) { console.log(line); }, function (err) { if (err) throw err; console.log("I'm done!!"); });
For more granular control,
open,
hasNextLine, and
nextLinemaybe be used to iterate a file (but you must
closeit yourself):
// or read line by line: lineReader.open('file.txt', function(err, reader) { if (err) throw err; if (reader.hasNextLine()) { reader.nextLine(function(err, line) { try { if (err) throw err; console.log(line); } finally { reader.close(function(err) { if (err) throw err; }); } }); } else { reader.close(function(err) { if (err) throw err; }); } });
You may provide additional options in a hash before the callbacks to
eachLineor
open: *
separator- a
stringor
RegExpseparator (defaults to
/\r\n?|\n/) *
encoding- file encoding (defaults to
'utf8') *
bufferSize- amount of bytes to buffer (defaults to 1024)
For example:
lineReader.eachLine('file.txt', {separator: ';', encoding: 'utf8'}, function(line, last, cb) { console.log(line); }); lineReader.open('file.txt', {bufferSize: 1024}, function(err, reader) { ... });
Both
eachLineand
opensupport passing either a file name or a read stream:
// reading from stdin lineReader.eachLine(process.stdin, function(line) {});// reading with file position boundaries var readStream = fs.createReadStream('test.log', { start: 0, end: 10000 }); lineReader.eachLine(readStream, function(line) {});
Note however that if you're reading user input from stdin then the readline module is probably a better choice.
eachLineand
openare compatible with
promisifyfrom bluebird:
var lineReader = require('line-reader'), Promise = require('bluebird');var eachLine = Promise.promisify(lineReader.eachLine); eachLine('file.txt', function(line) { console.log(line); }).then(function() { console.log('done'); }).catch(function(err) { console.error(err); });
If you're using a promise library that doesn't have a promisify function, here's how you can do it:
var lineReader = require('line-reader'), Promise = require(...);var eachLine = function(filename, options, iteratee) { return new Promise(function(resolve, reject) { lineReader.eachLine(filename, options, iteratee, function(err) { if (err) { reject(err); } else { resolve(); } }); }); } eachLine('file.txt', function(line) { console.log(line); }).then(function() { console.log('done'); }).catch(function(err) { console.error(err); });
Paul Em has also written a reverse-version of this gem to read files from bottom to top: reverse-line-reader.
Copyright 2011 Nick Ewing.