Node.js:计算文件中的行数

我有大的文本文件,其范围在30MB10GB之间。 如何使用Node.js文件中的行数?

我有这些限制:

  • 整个文件不需要写入内存
  • subprocess不需要执行任务

解决scheme不使用wc:

 var i; var count = 0; require('fs').createReadStream(process.argv[2]) .on('data', function(chunk) { for (i=0; i < chunk.length; ++i) if (chunk[i] == 10) count++; }) .on('end', function() { console.log(count); }); 

它速度较慢,但​​不是你可能期望的那么多 – 包括node.js加载和启动时间在内的140M +文件为0.6s

 >time node countlines.js video.mp4 619643 real 0m0.614s user 0m0.489s sys 0m0.132s >time wc -l video.mp4 619643 video.mp4 real 0m0.133s user 0m0.108s sys 0m0.024s >wc -c video.mp4 144681406 video.mp4 

你可以这样做,因为评论build议使用wc

 var exec = require('child_process').exec; exec('wc /path/to/file', function (error, results) { console.log(results); }); 

这是没有太多嵌套的另一种方法。

 var fs = require('fs'); filePath = process.argv[2]; fileBuffer = fs.readFileSync(filePath); to_string = fileBuffer.toString(); split_lines = to_string.split("\n"); console.log(split_lines.length-1); 
 var fs=require('fs'); filename=process.argv[2]; var data=fs.readFileSync(filename); var res=data.toString().split('\n').length; console.log(res-1);` 

我们可以使用indexOf让虚拟机find换行符:

 function countFileLines(filePath){ return new Promise((resolve, reject) => { let lineCount = 0; fs.createReadStream(filePath) .on("data", (buffer) => { let idx = -1; lineCount--; // Because the loop will run once for idx=-1 do { idx = buffer.indexOf(10, idx+1); lineCount++; } while (idx !== -1); }).on("end", () => { resolve(lineCount); }).on("error", reject); }); }; 

这个解决scheme的function是使用.indexOffind第一个换行符的位置。 它递增lineCount ,然后find下一个位置。 .indexOf的第二个参数告诉从哪里开始寻找换行符。 这样我们就跳过了大块的缓冲区。 while循环将为每个换行运行一次,再加一个。

我们让节点运行时执行search我们在较低的水平上实施,应该更快。

在我的系统上,这大约是在大文件(111 MB)上运行for循环缓冲区长度的两倍。

既然iojs 1.5.0有Buffer#indexOf()方法,用它来比较Andrey Sidorov的答案:

 ubuntu@server:~$ wc logs 7342500 27548750 427155000 logs ubuntu@server:~$ time wc -l logs 7342500 logs real 0m0.180s user 0m0.088s sys 0m0.084s ubuntu@server:~$ nvm use node Now using node v0.12.1 ubuntu@server:~$ time node countlines.js logs 7342500 real 0m2.559s user 0m2.200s sys 0m0.340s ubuntu@server:~$ nvm use iojs Now using node iojs-v1.6.2 ubuntu@server:~$ time iojs countlines2.js logs 7342500 real 0m1.363s user 0m0.920s sys 0m0.424s ubuntu@server:~$ cat countlines.js var i; var count = 0; require('fs').createReadStream(process.argv[2]) .on('data', function(chunk) { for (i=0; i < chunk.length; ++i) if (chunk[i] == 10) count++; }) .on('end', function() { console.log(count); }); ubuntu@server:~$ cat countlines2.js var i; var count = 0; require('fs').createReadStream(process.argv[2]) .on('data', function(chunk) { var index = -1; while((index = chunk.indexOf(10, index + 1)) > -1) count++ }) .on('end', function() { console.log(count); }); ubuntu@server:~$ 

你也可以使用indexOf():

 var index = -1; var count = 0; while ((index = chunk.indexOf(10, index + 1)) > -1) count++; 

有一个名为count-lines-in-file的npm模块。 我一直在使用它为小(<1000行)文件,迄今为止工作很好。