2016-11-17 1 views
0

Я столкнулся с неожиданным поведением в отношении fs.createReadStream и fs.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

в то время как, если я поток, как это:

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 преобразовывал в строковый тип ... :) –