2017-04-02 123 views
1

假設我有一個readable流,例如, request(URL)。我想通過fs.createWriteStream()將它的回覆寫在磁盤上,並在請求中填入管道。但同時我想通過crypto.createHash()流來計算下載數據的校驗和。如何從一個流中讀取並一次寫入多個?

readable -+-> calc checksum 
      | 
      +-> write to disk 

而且我想要在飛行中完成,而不是在內存中緩衝整個響應。

看來我可以使用oldschool on('data') hook來實現它。下面的僞代碼:

const hashStream = crypto.createHash('sha256'); 
hashStream.on('error', cleanup); 

const dst = fs.createWriteStream('...'); 
dst.on('error', cleanup); 

request(...).on('data', (chunk) => { 
    hashStream.write(chunk); 
    dst.write(chunk); 
}).on('end',() => { 
    hashStream.end(); 
    const checksum = hashStream.read(); 
    if (checksum != '...') { 
     cleanup(); 
    } else { 
     dst.end(); 
    } 
}).on('error', cleanup); 

function cleanup() { /* cancel streams, erase file */ }; 

但是這樣的方法看起來很尷尬。我試圖使用stream.Transformstream.Writable來實現像read | calc + echo | write這樣的東西,但我堅持實施。

回答

1

Node.js可讀流有一個.pipe方法,其工作方式與unix管道運算符非常相似,不同之處在於您可以流式傳輸js對象以及某種類型的字符串。

Here's a link to the doc on pipe

在你的情況下使用的一個例子可能是這樣的:

const req = request(...); 
req.pipe(dst); 
req.pipe(hash); 

請注意,您仍然有因爲他們不會傳播到處理每個數據流的錯誤和目的地都沒有如果可讀的錯誤關閉。

+0

謝謝!從文檔引用「可以將多個可寫流添加到單個可讀流中。」就是這個!我知道'pipe()',但它看起來像我錯過了這個設施。 –

相關問題