What is the most efficient way to read only the first line of a file in Node JS?
There's a built-in module almost for this case - readline
. It avoids messing with chunks and so forth. The code would look like the following:
const fs = require('fs');const readline = require('readline');async function getFirstLine(pathToFile) { const readable = fs.createReadStream(pathToFile); const reader = readline.createInterface({ input: readable }); const line = await new Promise((resolve) => { reader.on('line', (line) => { reader.close(); resolve(line); }); }); readable.close(); return line;}
I ended up adopting this solution, which seems the most performant I've seen so far:
var fs = require('fs');var Q = require('q');function readFirstLine (path) { return Q.promise(function (resolve, reject) { var rs = fs.createReadStream(path, {encoding: 'utf8'}); var acc = ''; var pos = 0; var index; rs .on('data', function (chunk) { index = chunk.indexOf('\n'); acc += chunk; index !== -1 ? rs.close() : pos += chunk.length; }) .on('close', function () { resolve(acc.slice(0, pos + index)); }) .on('error', function (err) { reject(err); }) });}
I created a npm module for convenience, named "firstline".
Thanks to @dandavis for the suggestion to use String.prototype.slice()
!
I know this doesn't exactly answer the question but for those who are looking for a READABLE and simple way to do so:
const fs = require('fs').promises;async function getFirstLine(filePath) { const fileContent = await fs.readFile(filePath, 'utf-8'); return (fileContent.match(/(^.*)/) || [])[1] || '';}
NOTE:
- naturaly, this will only work with text files, which I assumed you used from your description
- this will work with empty files and will return an empty string
- this regexp is very performant since it is simple (no
OR
conditions`or complex matches) and only reads the first line