With readable stream
var fs = require('fs');
function get_line(filename, line_no, callback) {
var stream = fs.createReadStream(filename, {
flags: 'r',
encoding: 'utf-8',
fd: null,
mode: 0666,
bufferSize: 64 * 1024
});
var fileData = '';
stream.on('data', function(data){
fileData += data;
// The next lines should be improved
var lines = fileData.split("
");
if(lines.length >= +line_no){
stream.destroy();
callback(null, lines[+line_no]);
}
});
stream.on('error', function(){
callback('Error', null);
});
stream.on('end', function(){
callback('File end reached without finding line', null);
});
}
get_line('./file.txt', 1, function(err, line){
console.log('The line: ' + line);
})
Direct solution:
You should use the slice method instead of a loop.
var fs = require('fs');
function get_line(filename, line_no, callback) {
var data = fs.readFileSync(filename, 'utf8');
var lines = data.split("
");
if(+line_no > lines.length){
throw new Error('File end reached without finding line');
}
callback(null, lines[+line_no]);
}
get_line('./file.txt', 9, function(err, line){
console.log('The line: ' + line);
})
for (var l in lines) isn't the most efficient way for looping over an array, you should do this instead:
for(var i = 0, iMax = lines.length; i < iMax; i++){/* lines[i] */ }
The asynchronous way:
var fs = require('fs');
function get_line(filename, line_no, callback) {
fs.readFile(filename, function (err, data) {
if (err) throw err;
// Data is a buffer that we need to convert to a string
// Improvement: loop over the buffer and stop when the line is reached
var lines = data.toString('utf-8').split("
");
if(+line_no > lines.length){
return callback('File end reached without finding line', null);
}
callback(null, lines[+line_no]);
});
}
get_line('./file.txt', 9, function(err, line){
console.log('The line: ' + line);
})
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…