2017-08-03 42 views
1

Brief:
系统将加载CSV文件,但它们预计为巨大(+ 1M行)。我已经知道如何使用队列和后台作业/任务来处理它们。如何知道一个文件中的行数,而不用在JavaScript中将内容加载到内存中?

但是,
我要显示给用户在他的文件中的进度,东西线:2165的1246875也许它的百分比。为了将它存档,我需要知道文件中的行数,但是我必须在不将内容加载到内存中的情况下进行操作,因此只要我上传并且可以将文件名保存在内存中,它就可以很快。在其中找到了全部的行。

在PHP中,这是使用SplFileObject试图seek()PHP_MAX_INT可能的,那么它进入文件和key()返回该行它能对最高点的连线。

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

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

[编辑]
想法而已:

  1. child_process.exec + wc -l(仅针对Unix)
  2. 获得来自客户端使用FileReader(代表资源给用户)此信息
+0

您可以读取一些第一行,计算行的平均大小并在其上划分文件大小。 –

+0

有人纠正我,如果我错了,但如果你阅读文件异步,并没有指定文件编码,你只处理块,对吧?那么你可以计算每个块中的换行符并让该块进行垃圾回收吗? –

+1

你不需要计数线。跟踪已处理字节的数量并将其除以文件长度以知道已处理文件的数量。乘以100以百分比表示。 – axiac

回答

0

你会使用一个流如记录here

以下示例应该能够使用第一个参数作为文件名的文件中的行数。

即: 节点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); 
}); 
+0

谢谢,但它接缝,这并不妨碍文件内容被添加到内存。我测试了一个134.091.524字节的CSV和Node的'process.memoryUsage()'报告了106.373.180字节的外部使用情况。 –

1

这是不可能的。

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

wc和PHP的SplFileObject这两个流都是整个文件,他们不做魔术。所以最好的答案是哪种方法以最有效的方式来做到这一点。这意味着什么GC可以更好地运行。

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

虽然它将文件内容带到内存中,但Joel Lord答案是Node.js解决方案的答案。你也可以看看readline module

+0

*知道这个字节有多少行包含计数换行*正确。你也可以将“计数行”看作实际上“计数换行符”(称为“换行符”可能会让某些人感到困惑),因为这就是“行”的定义。 * *换行符,你必须找到*全部*。这意味着读取*整个*文件。 –

相关问题