Asynchronous, buffered, line-by-line file/stream reader with support for user-defined line separators.
npm install line-reader
The eachLine
function 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
}
});
eachLine
can 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 false
from 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 nextLine
maybe be used
to iterate a file (but you must close
it 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 eachLine
or open
:
separator
- astring
orRegExp
separator (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 eachLine
and open
support 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.
eachLine
and open
are compatible with promisify
from 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);
});
- Nick Ewing
- Andy Edwards (jedwards1211)
- Jameson Little (beatgammit)
- Masum (masumsoft)
- Matthew Caruana Galizia (mattcg)
- Ricardo Bin (ricardohbin)
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.