簡體   English   中英

合並Node.js流

[英]Merging Node.js streams

我有一堆文件,我從對應的多個流中讀取,處理並將某些數據合並到單個流中。

有沒有比下面更優雅的解決方案(有一個單獨的計數器,在所有源流發出end之后調用combinedStream.end() ):

let combinedStream = ....;

let counter = 0;

filePaths.forEach(function(filePath) {
  counter += 1;
  const fileStream = fs.createReadStream(filePath);
  const myStream = new MyStream(fileStream);

  myStream.on('data', myStream.write);
  myStream.on('end', function() {
    counter -= 1;
    if (counter === 0) {
      combinedStream.end();
    }
  });
});

return combinedStream;

一種更清潔的方法可能是該回購中使用的方法,盡管它只不過是將計數器隱藏在某個地方並讓您處理更舒適的基於回調的模型而已。

這樣,您的代碼將如下所示:

let sharedStream = ...

function onEachFilename(filename, callback) {
    // here you can read from the stream and push the data on the shared one,
    // then invoke the "internal" callback on the end event
}

function onEndAll() {
    // here you can finalize and close the shared stream
}

forEach(filenames, onEachFilename, onEndAll);

請記住,某個地方仍然有一個函數負責為您計數,並在所有callback函數都被調用后調用onEnd函數。

您可以只使用Transform流處理文件,然后通過管道傳遞到PassThrough流。

由於您正在使用let ,所以我想您可以使用ES2015。

  "use strict";

 let fs=require('fs');
 let filePaths=['./tmp/h.txt','./tmp/s.txt'];


 let Stream = require('stream');

  class StreamProcessor  {

   constructor() {
    this.process_streams = [];
   }

   push (source_stream) { 
   // Create a new Transform Stream
   let transform = new StreamTransformer();
    // Register the finish event and pipe
  transform.processed = transform.wait.call(transform);
   source_stream.pipe(transform);
   // push the stream to the internal array
  this.process_streams.push(transform);
   }

   done (callback) {  
    let streams = this.process_streams;
 // Wait for all Transform streams to finish processing
   Promise.all( 
   streams.map(function(s) {return s.processed; })
   )
   .then ( function() {
   let combined_stream=new Stream.PassThrough();
   streams.forEach(function (stream) {
   stream.pipe(combined_stream); 
   });
   // Call the callback with stream
    callback(null,combined_stream);
   })
   .catch(function (err) {
    callback(err);
    });
   }

   }     

  class StreamTransformer extends Stream.Transform {
     constructor () {
     // call super
     super();
     } 

     _transform(chunk,enc, transformed) {
     // process files here 
     let data=chunk.toString();
      data=data.substring(0,data.length-2);
     this.push(data);
     transformed();
     }

     _flush(flushed) {
     // for additonal at end
     this.push('\n');
     flushed();
     }

    wait() {
    // returns a promise that resolves, when all the data is processed;
    let stream = this;

    return new Promise(function(resolve,reject)  {
   stream.on('finish', function() {
   resolve(true); });
   stream.on('error', function(err) {
   reject(err);
   });
    });

    }

  }

  ///  Now you can do..

  let process_stream = new StreamProcessor(); 

   filePaths.forEach(function (fpath) {
   let fstream = fs.createReadStream(fpath);
   process_stream.push(fstream);
  });

   process_stream.done(  function
    (err,combined_stream) {
 // Consume the combines stream
 combined_stream.pipe(process.stdout);
  });

測試文件包含“ hello”和“ stream”

     // Outputs is
    // hell
   // stream 

這可以進一步改善。 :/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM