2016-11-17 66 views
0

我遇到了意外的行为,涉及fs.createReadStreamfs.createWriteStream。我希望有人能指出,我做出了错误的假设:可读可写的流意外行为

我创建这样

let readableStream = fs.createReadStream('./lorem ipsum.doc'); 
let writableStream = fs.createWriteStream('./output'); 

可读和可写流为什么,如果我读流发送到写入流这样

let data, chunk; 
readableStream 
.on('readable',() => { 
    while ((chunk=stream.read()) !== null) { 
     data+=chunk; 
    } 
}) 
.on('end',()=>{ 
    writableStream.write(data) 
    console.log("done"); 
}); 

我结束了在输出文件差异

Output file with discrepancy

而如果I流是这样的:

let data, chunk; 
readableStream 
.on('readable',() => { 
    while ((chunk=stream.read()) !== null) { 
     writableStream.write(chunk) 
    } 
}) 
.on('end',()=>{ 
    console.log("done"); 
}); 

所有细而如预期:

Expected output

即,在第一例中,何时/何是以字节为单位的额外开销添加?为什么添加?出了什么问题?

感谢您的启发!


注:我知道使用pipe(这给了我正确的输出文件),但这些例子只是我的理解。

回答

1

我猜测的重点是在第一个演示中,您使用'data + =',它将二进制流转换为字符串,并浪费了一些空间。你可以尝试转换第二个演示吗? ===>

var s=chunk; 
writableStream.write(s); 

更新:结合流缓冲区正确的方法是像您的评论:

var chunks = []; 
var size = 0; 
...on('data', function(chunk){ 
    chunks.push(chunk); 
    size += chunk.length; 
}) 
...on('end', function(){ 
    var buf = Buffer.concat(chunks, size); // use buf to write to writestream 
    var str = iconv.decode(buf, 'utf8'); // use str to console.log string, which supports all languages such as Asian 
}) 
+0

是的,你说得对。如果我做'let data = Buffer.from([]);',然后使用'data = Buffer.concat([data,chunk]);',文件就出来了。我愚蠢的,我没有意识到我正在转换为字符串类型。 –

+0

或者实际上,这个JavaScript转换为字符串类型... :) –