node.js:将一个文本文件读入一个数组。 (每行在数组中的一个项目。)

我想在node.js中将一个非常大的文件读入JavaScript数组中。

所以如果这个文件是这样的:

first line two three ... ... 

我会有arrays:

 ['first line','two','three', ... , ... ] 

该函数看起来像这样:

 var array = load(filename); 

因此,把它全部作为一个string加载然后拆分的想法是不可接受的。

如果你可以把最后的数据放入一个数组中,那么你是否也可以把它放在一个string中并按照build议分割? 无论如何,如果你想一次处理文件一行,你也可以尝试这样的:

 var fs = require('fs'); function readLines(input, func) { var remaining = ''; input.on('data', function(data) { remaining += data; var index = remaining.indexOf('\n'); while (index > -1) { var line = remaining.substring(0, index); remaining = remaining.substring(index + 1); func(line); index = remaining.indexOf('\n'); } }); input.on('end', function() { if (remaining.length > 0) { func(remaining); } }); } function func(data) { console.log('Line: ' + data); } var input = fs.createReadStream('lines.txt'); readLines(input, func); 

编辑:(在回应phopkins评论)我认为(至less在较新的版本)子string不会复制数据,但创build一个特殊的SlicedString对象(快速浏览一下v8源代码)。 在任何情况下,这是一个修改,避免所提到的子string(testing在一个文件几兆字节的“所有的工作,没有玩耍,使杰克一个愚蠢的男孩”):

 function readLines(input, func) { var remaining = ''; input.on('data', function(data) { remaining += data; var index = remaining.indexOf('\n'); var last = 0; while (index > -1) { var line = remaining.substring(last, index); last = index + 1; func(line); index = remaining.indexOf('\n', last); } remaining = remaining.substring(last); }); input.on('end', function() { if (remaining.length > 0) { func(remaining); } }); } 

同步:

 var fs = require('fs'); var array = fs.readFileSync('file.txt').toString().split("\n"); for(i in array) { console.log(array[i]); } 

asynchronous:

 var fs = require('fs'); fs.readFile('file.txt', function(err, data) { if(err) throw err; var array = data.toString().split("\n"); for(i in array) { console.log(array[i]); } }); 

使用Node.js readline模块 。

 var fs = require('fs'); var readline = require('readline'); var filename = process.argv[2]; readline.createInterface({ input: fs.createReadStream(filename), terminal: false }).on('line', function(line) { console.log('Line: ' + line); }); 

有了BufferedReader ,但该函数应该是asynchronous的:

 var load = function (file, cb){ var lines = []; new BufferedReader (file, { encoding: "utf8" }) .on ("error", function (error){ cb (error, null); }) .on ("line", function (line){ lines.push (line); }) .on ("end", function (){ cb (null, lines); }) .read (); }; load ("file", function (error, lines){ if (error) return console.log (error); console.log (lines); }); 

使用readline( 文档 )。 这里有一个例子,读取一个css文件,parsing图标并将其写入json

 var results = []; var rl = require('readline').createInterface({ input: require('fs').createReadStream('./assets/stylesheets/_icons.scss') }); // for every new line, if it matches the regex, add it to an array // this is ugly regex :) rl.on('line', function (line) { var re = /\.icon-icon.*:/; var match; if ((match = re.exec(line)) !== null) { results.push(match[0].replace(".",'').replace(":",'')); } }); // readline emits a close event when the file is read. rl.on('close', function(){ var outputFilename = './icons.json'; fs.writeFile(outputFilename, JSON.stringify(results, null, 2), function(err) { if(err) { console.log(err); } else { console.log("JSON saved to " + outputFilename); } }); }); 

这是@mtomis上面的答案的变体。

它创造了一系列的线条。 它发出'数据'和'结束'事件,让你处理stream的结束。

 var events = require('events'); var LineStream = function (input) { var remaining = ''; input.on('data', function (data) { remaining += data; var index = remaining.indexOf('\n'); var last = 0; while (index > -1) { var line = remaining.substring(last, index); last = index + 1; this.emit('data', line); index = remaining.indexOf('\n', last); } remaining = remaining.substring(last); }.bind(this)); input.on('end', function() { if (remaining.length > 0) { this.emit('data', remaining); } this.emit('end'); }.bind(this)); } LineStream.prototype = new events.EventEmitter; 

用它作为包装:

 var lineInput = new LineStream(input); lineInput.on('data', function (line) { // handle line }); lineInput.on('end', function() { // wrap it up }); 

使用JFile包的file.lines

 var JFile=require('jfile'); var myF=new JFile("./data.txt"); myF.lines // ["first line","second line"] .... 

不要忘记之前:

 npm install jfile --save 

我只是想添加@finbarr伟大的答案,在asynchronous的例子中的一点点修复:

asynchronous:

 var fs = require('fs'); fs.readFile('file.txt', function(err, data) { if(err) throw err; var array = data.toString().split("\n"); for(i in array) { console.log(array[i]); } done(); }); 

@MadPhysicist,done()是什么释放asynchronous。 呼叫。

我有同样的问题,我已经逐行解决了模块

https://www.npmjs.com/package/line-by-line

至less对我来说,就像是魅力一样,无论是同步还是asynchronous模式。

另外,线路终止不终止的问题可以用下面的选项来解决:

 { encoding: 'utf8', skipEmptyLines: false } 

线路的同步处理:

 var LineByLineReader = require('line-by-line'), lr = new LineByLineReader('big_file.txt'); lr.on('error', function (err) { // 'err' contains error object }); lr.on('line', function (line) { // 'line' contains the current line without the trailing newline character. }); lr.on('end', function () { // All lines are read, file is closed now. }); 

要将大文件读入数组,您可以逐行读取块或逐块读取。

一行一行的参考我的答案在这里

 var fs = require('fs'), es = require('event-stream'), var lines = []; var s = fs.createReadStream('filepath') .pipe(es.split()) .pipe(es.mapSync(function(line) { //pause the readstream s.pause(); lines.push(line); s.resume(); }) .on('error', function(err) { console.log('Error:', err); }) .on('end', function() { console.log('Finish reading.'); console.log(lines); }) ); 

块大块参考这篇文章

 var offset = 0; var chunkSize = 2048; var chunkBuffer = new Buffer(chunkSize); var fp = fs.openSync('filepath', 'r'); var bytesRead = 0; while(bytesRead = fs.readSync(fp, chunkBuffer, 0, chunkSize, offset)) { offset += bytesRead; var str = chunkBuffer.slice(0, bytesRead).toString(); var arr = str.split('\n'); if(bytesRead = chunkSize) { // the last item of the arr may be not a full line, leave it to the next chunk offset -= arr.pop().length; } lines.push(arr); } console.log(lines);