Een beschrijfbare stream implementeren

Ik wil gegevens van een Amazon Kinesis-stream naar een s3-log of een bunyan-log leiden.

Het voorbeeld werkt met een bestandsschrijfstroom of stdout. Hoe zou ik mijn eigen schrijfbare stream implementeren?

//this works
var file = fs.createWriteStream('my.log')
kinesisSource.pipe(file)

dit werkt niet door te zeggen dat het geen methode ‘aan’ heeft

var stream = {}; //process.stdout works however
stream.writable = true;
stream.write =function(data){
    console.log(data);
};
kinesisSource.pipe(stream);

welke methoden moet ik implementeren voor mijn eigen aangepaste schrijfbare stream, de documenten lijken aan te geven dat ik ‘write’ moet implementeren en niet ‘on’


Antwoord 1, autoriteit 100%

Om je eigen schrijfbare stream te maken, heb je drie mogelijkheden.

Maak je eigen klas

Hiervoor heb je 1) nodig om de Writable-klasse uit te breiden 2) om de Writable-constructor in je eigen constructor aan te roepen 3) definieer een _write()-methode in het prototype van je stream-object.

Hier is een voorbeeld:

var stream = require('stream');
var util = require('util');
function EchoStream () { // step 2
  stream.Writable.call(this);
};
util.inherits(EchoStream, stream.Writable); // step 1
EchoStream.prototype._write = function (chunk, encoding, done) { // step 3
  console.log(chunk.toString());
  done();
}
var myStream = new EchoStream(); // instanciate your brand new stream
process.stdin.pipe(myStream);

Een leeg beschrijfbaar object verlengen

In plaats van een nieuw objecttype te definiëren, kunt u een leeg Writableobject maken en de _write()methode implementeren:

var stream = require('stream');
var echoStream = new stream.Writable();
echoStream._write = function (chunk, encoding, done) {
  console.log(chunk.toString());
  done();
};
process.stdin.pipe(echoStream);

Gebruik de vereenvoudigde constructor-API

Als je io.js gebruikt, kun je de vereenvoudigde constructor-APIgebruiken:

var writable = new stream.Writable({
  write: function(chunk, encoding, next) {
    console.log(chunk.toString());
    next();
  }
});

Gebruik een ES6-klasse in Node 4+

class EchoStream extends stream.Writable {
  _write(chunk, enc, next) {
    console.log(chunk.toString());
    next();
  }
}

Antwoord 2, autoriteit 7%

Eigenlijk is het vrij eenvoudig om een ​​beschrijfbare stream te maken.
Hier is het voorbeeld:

var fs = require('fs');
var Stream = require('stream');
var ws = new Stream;
ws.writable = true;
ws.bytes = 0;
ws.write = function(buf) {
   ws.bytes += buf.length;
}
ws.end = function(buf) {
   if(arguments.length) ws.write(buf);
   ws.writable = false;
   console.log('bytes length: ' + ws.bytes);
}
fs.createReadStream('file path').pipe(ws);

Ook als je je eigen klas wilt maken, geef @Paul een goed antwoord.


Antwoord 3

Hier is een voorbeeld rechtstreeks uit nodejs docs
https://nodejs.org/api/stream.html#an- voorbeeld-schrijfbare-stream

const { Writable } = require('stream');
class MyWritable extends Writable {
  _write(chunk, encoding, callback) {
    if (chunk.toString().indexOf('a') >= 0) {
      callback(new Error('chunk is invalid'));
    } else {
      callback();
    }
  }
}

Other episodes