2014-07-27 81 views
1

我一直在玩可讀和變換流,我無法解決消失線的奧祕。Node.js流和數據消失

考慮一個文本文件中的行包含順序編號,從1到20000:

$ seq 1 20000 > file.txt 

我創建了一個Readable流和LineStream(從庫調用署名npm install byline;我使用4.1.1版本):

var file = (require('fs')).createReadStream('file.txt'); 
var lines = new (require('byline').LineStream)(); 

考慮下面的代碼:

setTimeout(function() { 
    lines.on('readable', function() { 
    var line; 
    while (null !== (line = lines.read())) { 
     console.log(line); 
    } 
    }); 
}, 1500); 

setTimeout(function() { 
    file.on('readable', function() { 
    var chunk; 
    while (null !== (chunk = file.read())) { 
     lines.write(chunk); 
    } 
    }); 
}, 1000); 

注意,它首先附加一個監聽到'readable'事件file可讀流的,其寫入到lines流,並且只有一半的第二以後它附加一個監聽到'readable'事件lines流的,其簡單地打印線路到控制檯。

如果我運行此代碼,它將只打印16384(即2^14)行並停止。它不會完成文件。但是,如果我將1500毫秒超時更改爲500毫秒 - 有效地交換偵聽器的連接順序,它將愉快地打印整個文件。

我試着玩highWaterMark,指定從文件流中讀取的字節數量,將監聽器附加到行流的其他事件,都是徒勞的。

什麼能解釋這種行爲?

謝謝!

回答

2

我認爲這種行爲可以用兩兩件事來說明:

  1. 你如何使用流。
  2. byline如何工作。

你要做的是手動管道。問題在於它不尊重highWaterMark並強制整體被緩衝。

所有這些導致byline表現不佳。看到這個:https://github.com/jahewson/node-byline/blob/master/lib/byline.js#L110-L112。這意味着當緩衝區長度> highWaterMark時,它會停止按下行。但這沒有任何意義!它不會阻止內存使用量的增長(行仍然存儲在特殊的行緩衝區中),但流不知道這些行,並且如果它以溢出狀態結束,它們將永遠丟失。

你可以做什麼:

  1. 使用pipe
  2. 修改highWaterMarklines._readableState.highWaterMark = Infinity;
  3. 使用byline
+0

感謝停止!這完全解釋了它。我已經通過在線的源代碼瀏覽過,但是我相信我缺乏Node的經驗。js(尤其是它的流)讓我很難看到這個問題。 –