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);