2017-08-03 22 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

*知道這個字節有多少行包含計數換行*正確。你也可以將「計數行」看作實際上「計數換行符」(稱爲「換行符」可能會讓某些人感到困惑),因爲這就是「行」的定義。 * *換行符,你必須找到*全部*。這意味着讀取*整個*文件。 –

相關問題