如何知道一个文件中的行数,而无需将其内容加载到JavaScript中的内存?

简要:
一个将加载CSV文件的系统,但预计会很大 (+ 1M行)。 我已经知道如何使用队列和后台作业/任务来处理它们。

但,
我想向用户显示他的文件中的进度,如下所示: 1246875的2165或者百分比。 要存档这个,我需要知道文件中的行数,但是我不得不将它的内容加载到内存中,所以它可以很快,只要我上传,可以保存文件中的文件在其中find了全部的行。

在PHP中,这可能使用SplFileObject试图seek()PHP_MAX_INT ,然后它到达它可以在文件中的最高行, key()返回该行。

但是这个系统是完全用JavaScript / Node.js构build的,所以为了方便,我想用JavaScript来构build这个系统部分。

我怎么能做到这一点? 已经看过FS API了 ,但没有find如何去做到这一点。

[编辑]
迄今为止的想法:

  1. child_process.exec + wc -l (仅适用于Unix)
  2. 使用FileReader从客户端获取此信息(将资源委托给用户)

这是不可能的。

行是关于文件的人类概念。 对于电脑来说,文件只是一堆字节, 你可以知道总字节数,你可以寻找思想字节的长度,但知道这个字节有多less行已经包括计算换行符和计算换行符来读取它们。

wc和PHP的SplFileObject可以对整个文件进行stream式处理,但是他们并没有做到这一点。 所以最好的答案是哪种方法以最有效的方式来做到这一点。 这意味着什么GC会更好地运作。

另一方面,如果精度不是要求,你可以尝试猜测。 如果所有行都有固定的字节长度,则可以将其除以文件的总字节数。 或者,正如Aikon所指出的那样 ,你可以只读几个字节(它们分成几行)得到它们的平均长度,并除以文件的总字节数。

虽然它将文件内容带入内存, Joel Lord的答案是Node.js解决scheme的答案。 你也可以看看readline模块 。

您将使用这里logging的stream

下面的例子应该可以使用第一个参数作为文件名的文件中的行数。

即:节点countlines.js nameoffiletocountthelines.csv

 var fs = require("fs"); var lines = 0; //Using the first argument as the filename var filename = process.argv[2]; var stream = fs.createReadStream(filename) //When data is received, check all the character codes and //if we find a carriage return, increment the line counter stream.on("data", function(chunk) { for(var i = 0; i < chunk.length; i++) { if (chunk[i] == 10 || chunk[i] == 13) lines++; } }); //When the file processing is done, echo the number of lines stream.on("end", function() { console.log("Lines: " + lines); });