Errors While Writing
It is recommended that errors occurring during the processing of the and methods are reported by invoking the callback and passing the error as the first argument.
This will cause an event to be emitted by the
Throwing an from within can result in unexpected and inconsistent behavior depending on how the stream is being used.
Using the callback ensures consistent and predictable handling of errors.
If a stream pipes into a stream when emits an error, the stream will be unpiped.
An Example Writable Stream
The following illustrates a rather simplistic (and somewhat pointless) custom stream implementation.
While this specific stream instance is not of any real particular usefulness, the example illustrates each of the required elements of a custom stream instance:
Decoding buffers in a Writable Stream
Decoding buffers is a common task, for instance, when using transformers whose input is a string.
This is not a trivial process when using multi-byte characters encoding, such as UTF-8.
The following example shows how to decode multi-byte strings using and
Implementing a Readable Stream
The class is extended to implement a stream.
Custom streams must call the constructor and implement the method.
The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource.
If specified, then buffers will be decoded to strings using the specified encoding.
Whether this stream should behave as a stream of objects.
Meaning that returns a single value instead of a of size
Implementation for the method.
Number of bytes to read asynchronously
It should be implemented by child classes, and called by the internal class methods only.
All stream implementations must provide an implementation of the method to fetch data from the underlying resource.
When is called, if data is available from the resource, the implementation should begin pushing that data into the read queue using the method.
should continue reading from the resource and pushing data until returns
Only when is called again after it has stopped should it resume pushing additional data onto the queue.
Once the method has been called, it will not be called again until the method is called.
is guaranteed to be called only once within a synchronous execution, i.e. a microtick.
The argument is advisory.
For implementations where a "read" is a single operation that returns data can use the argument to determine how much data to fetch.
Other implementations may ignore this argument and simply provide data whenever it becomes available.
There is no need to "wait" until bytes are available before calling
The method is prefixed with an underscore because it is internal to the class that defines it, and should never be called directly by user programs.
Chunk of data to push into the read queue.
For streams not operating in object mode, must be a string, or
Encoding of string chunks.
Must be a valid encoding, such as or
if additional chunks of data may continued to be pushed; otherwise.
When is a, or, the of data will be added to the internal queue for users of the stream to consume.
Passing as signals the end of the stream (EOF), after which no more data can be written.
When the is operating in paused mode, the data added with can be read out by calling the method when the event is emitted.
When the is operating in flowing mode, the data added with will be delivered by emitting a event.
The method is designed to be as flexible as possible.
For example, when wrapping a lower-level source that provides some form of pause/resume mechanism, and a data callback, the low-level source can be wrapped by the custom instance as illustrated in the following example:
source is an object with and methods, and an member that gets called when it has data, and an member that gets called when the data is over.
Every time there's data, push it into the internal buffer.
if returns, then stop reading from source
When the source ends, push the EOF-signaling chunk
will be called when the stream wants to pull more data in
the advisory size argument is ignored in this case.
The method is intended be called only by implementers, and only from within the method.
For streams not operating in object mode, if the parameter of is, it will be treated as empty string or buffer.
See for more information.
Errors While Reading
It is recommended that errors occurring during the processing of the method are emitted using the event rather than being thrown.
Throwing an from within can result in unexpected and inconsistent behavior depending on whether the stream is operating in flowing or paused mode.
Using the event ensures consistent and predictable handling of errors.
do some work
An Example Counting Stream
The following is a basic example of a stream that emits the numerals from 1 to 1,000,000 in ascending order, and then ends.
Implementing a Duplex Stream
A stream is one that implements both and such as a TCP socket connection.
to extending the and classes).
The class prototypically inherits from and parasitically from, but will work properly for both base classes due to overriding on
Custom streams must call the constructor and implement both the and methods.
Passed to both and constructors.
Also has the following fields:
If set to, then the stream will automatically end the writable side when the readable side ends.
Sets for readable side of the stream.
Has no effect if is
An Example Duplex Stream
The following illustrates a simple example of a stream that wraps a hypothetical lower-level source object to which data can be written, and from which data can be read, albeit using an API that is not compatible with Node.js streams.
The following illustrates a simple example of a stream that buffers incoming written data via the interface that is read back out via the interface.
The underlying source only deals with strings
The most important aspect of a stream is that the and sides operate independently of one another despite co-existing within a single object instance.
Object Mode Duplex Streams
For streams, can be set exclusively for either the or side using the and options respectively.
Coerce the chunk to a number if necessary
Transform the chunk into something else.
Push the data onto the readable queue.