2016-03-22 38 views
0

假设我有一个包含整数列表的文件,每行一个。我使用fs.createReadStream和管道split(使每个块是一个整数)。然后我把它变成一个复式流,它应该添加数字并且通过管道输入fs.createWriteStream在允许读取之前等待上一个流为空

var fs = require('fs'); 
var stream = require('stream'); 
var split = require('split'); 

var addIntegers = new stream.Duplex(); 

addIntegers.sum = 0; 

addIntegers._read = function(size) { 
    this.push(this.sum + '\n'); 
} 

addIntegers._write = function(chunk, encoding, done) { 
    this.sum += +chunk; 
    done(); 
} 

fs.createReadStream('list-of-integers.txt') 
    .pipe(split()) 
    .pipe(addIntegers) 
    .pipe(fs.createWriteStream('sum.txt')); 

当我运行此,sum.txt只是被不断地以零填充和程序永远不会终止(如预期)。在允许输出流(fs.createWriteStream)从addIntegers中读取之前,如何等待输入流(split)为空?

+1

为什么'push()'在_write()里面呢? – mscdex

+0

嗯是的,我可以在'_write'中使用变换流和this.push(this.sum +'\ n')'。我以这种方式得到了一个总得分比永远好得多的总分。但是,有什么办法可以获得总体总数? (一次写入'sum.txt'而不是n次?)。后来我意识到我可以“尾随-n 1 sum.txt”,但我想知道是否有一种惯用的'节点'方式来获得我想要的。 – aeoliant

回答

0

我想通了。

我决定使用一个Transform流代替(谢谢mscdex),因为它有一个方法(_flush),在所有写入数据被消耗后被调用。工作代码如下。不要忘了npm i split :)

var fs = require('fs'); 
var stream = require('stream'); 
var split = require('split'); 

var addIntegers = new stream.Transform(); 

addIntegers.sum = 0; 

addIntegers._transform = function(chunk, encoding, done) { 
    this.sum += +chunk; 
    done(); 
} 

addIntegers._flush = function(done) { 
    this.push(this.sum + '\n'); 
} 

fs.createReadStream('list-of-integers.txt') 
    .pipe(split()) 
    .pipe(addIntegers) 
    .pipe(fs.createWriteStream('sum.txt')); 
相关问题