2731 lines
196 KiB
HTML
2731 lines
196 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width">
|
||
<meta name="nodejs.org:node-version" content="v12.22.12">
|
||
<title>Stream | Node.js v12.22.12 Documentation</title>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic&display=fallback">
|
||
<link rel="stylesheet" href="assets/style.css">
|
||
<link rel="stylesheet" href="assets/hljs.css">
|
||
<link rel="canonical" href="https://nodejs.org/api/stream.html">
|
||
</head>
|
||
<body class="alt apidoc" id="api-section-stream">
|
||
<div id="content" class="clearfix">
|
||
<div id="column2" class="interior">
|
||
<div id="intro" class="interior">
|
||
<a href="/" title="Go back to the home page">
|
||
Node.js
|
||
</a>
|
||
</div>
|
||
<ul>
|
||
<li><a href="documentation.html" class="nav-documentation">About this documentation</a></li>
|
||
<li><a href="synopsis.html" class="nav-synopsis">Usage and example</a></li>
|
||
</ul>
|
||
<hr class="line">
|
||
<ul>
|
||
<li><a href="assert.html" class="nav-assert">Assertion testing</a></li>
|
||
<li><a href="async_hooks.html" class="nav-async_hooks">Async hooks</a></li>
|
||
<li><a href="buffer.html" class="nav-buffer">Buffer</a></li>
|
||
<li><a href="addons.html" class="nav-addons">C++ Addons</a></li>
|
||
<li><a href="n-api.html" class="nav-n-api">C/C++ Addons with N-API</a></li>
|
||
<li><a href="embedding.html" class="nav-embedding">C++ Embedder API</a></li>
|
||
<li><a href="child_process.html" class="nav-child_process">Child Processes</a></li>
|
||
<li><a href="cluster.html" class="nav-cluster">Cluster</a></li>
|
||
<li><a href="cli.html" class="nav-cli">Command line options</a></li>
|
||
<li><a href="console.html" class="nav-console">Console</a></li>
|
||
<li><a href="crypto.html" class="nav-crypto">Crypto</a></li>
|
||
<li><a href="debugger.html" class="nav-debugger">Debugger</a></li>
|
||
<li><a href="deprecations.html" class="nav-deprecations">Deprecated APIs</a></li>
|
||
<li><a href="dns.html" class="nav-dns">DNS</a></li>
|
||
<li><a href="domain.html" class="nav-domain">Domain</a></li>
|
||
<li><a href="errors.html" class="nav-errors">Errors</a></li>
|
||
<li><a href="events.html" class="nav-events">Events</a></li>
|
||
<li><a href="fs.html" class="nav-fs">File system</a></li>
|
||
<li><a href="globals.html" class="nav-globals">Globals</a></li>
|
||
<li><a href="http.html" class="nav-http">HTTP</a></li>
|
||
<li><a href="http2.html" class="nav-http2">HTTP/2</a></li>
|
||
<li><a href="https.html" class="nav-https">HTTPS</a></li>
|
||
<li><a href="inspector.html" class="nav-inspector">Inspector</a></li>
|
||
<li><a href="intl.html" class="nav-intl">Internationalization</a></li>
|
||
<li><a href="modules.html" class="nav-modules">Modules: CommonJS modules</a></li>
|
||
<li><a href="esm.html" class="nav-esm">Modules: ECMAScript modules</a></li>
|
||
<li><a href="module.html" class="nav-module">Modules: <code>module</code> API</a></li>
|
||
<li><a href="packages.html" class="nav-packages">Modules: Packages</a></li>
|
||
<li><a href="net.html" class="nav-net">Net</a></li>
|
||
<li><a href="os.html" class="nav-os">OS</a></li>
|
||
<li><a href="path.html" class="nav-path">Path</a></li>
|
||
<li><a href="perf_hooks.html" class="nav-perf_hooks">Performance hooks</a></li>
|
||
<li><a href="policy.html" class="nav-policy">Policies</a></li>
|
||
<li><a href="process.html" class="nav-process">Process</a></li>
|
||
<li><a href="punycode.html" class="nav-punycode">Punycode</a></li>
|
||
<li><a href="querystring.html" class="nav-querystring">Query strings</a></li>
|
||
<li><a href="readline.html" class="nav-readline">Readline</a></li>
|
||
<li><a href="repl.html" class="nav-repl">REPL</a></li>
|
||
<li><a href="report.html" class="nav-report">Report</a></li>
|
||
<li><a href="stream.html" class="nav-stream active">Stream</a></li>
|
||
<li><a href="string_decoder.html" class="nav-string_decoder">String decoder</a></li>
|
||
<li><a href="timers.html" class="nav-timers">Timers</a></li>
|
||
<li><a href="tls.html" class="nav-tls">TLS/SSL</a></li>
|
||
<li><a href="tracing.html" class="nav-tracing">Trace events</a></li>
|
||
<li><a href="tty.html" class="nav-tty">TTY</a></li>
|
||
<li><a href="dgram.html" class="nav-dgram">UDP/datagram</a></li>
|
||
<li><a href="url.html" class="nav-url">URL</a></li>
|
||
<li><a href="util.html" class="nav-util">Utilities</a></li>
|
||
<li><a href="v8.html" class="nav-v8">V8</a></li>
|
||
<li><a href="vm.html" class="nav-vm">VM</a></li>
|
||
<li><a href="wasi.html" class="nav-wasi">WASI</a></li>
|
||
<li><a href="worker_threads.html" class="nav-worker_threads">Worker threads</a></li>
|
||
<li><a href="zlib.html" class="nav-zlib">Zlib</a></li>
|
||
</ul>
|
||
<hr class="line">
|
||
<ul>
|
||
<li><a href="https://github.com/nodejs/node" class="nav-https-github-com-nodejs-node">Code repository and issue tracker</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div id="column1" data-id="stream" class="interior">
|
||
<header>
|
||
<h1>Node.js v12.22.12 Documentation</h1>
|
||
<div id="gtoc">
|
||
<ul>
|
||
<li>
|
||
<a href="index.html">Index</a>
|
||
</li>
|
||
<li>
|
||
<a href="all.html">View on single page</a>
|
||
</li>
|
||
<li>
|
||
<a href="stream.json">View as JSON</a>
|
||
</li>
|
||
|
||
<li class="version-picker">
|
||
<a href="#">View another version <span>▼</span></a>
|
||
<ol class="version-picker"><li><a href="https://nodejs.org/docs/latest-v17.x/api/stream.html">17.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v16.x/api/stream.html">16.x <b>LTS</b></a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v15.x/api/stream.html">15.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v14.x/api/stream.html">14.x <b>LTS</b></a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v13.x/api/stream.html">13.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v12.x/api/stream.html">12.x <b>LTS</b></a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v11.x/api/stream.html">11.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v10.x/api/stream.html">10.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v9.x/api/stream.html">9.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v8.x/api/stream.html">8.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v7.x/api/stream.html">7.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v6.x/api/stream.html">6.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v5.x/api/stream.html">5.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v4.x/api/stream.html">4.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v0.12.x/api/stream.html">0.12.x</a></li>
|
||
<li><a href="https://nodejs.org/docs/latest-v0.10.x/api/stream.html">0.10.x</a></li></ol>
|
||
</li>
|
||
|
||
<li class="edit_on_github"><a href="https://github.com/nodejs/node/edit/master/doc/api/stream.md"><span class="github_icon"><svg height="16" width="16" viewBox="0 0 16.1 16.1" fill="currentColor"><path d="M8 0a8 8 0 0 0-2.5 15.6c.4 0 .5-.2.5-.4v-1.5c-2 .4-2.5-.5-2.7-1 0-.1-.5-.9-.8-1-.3-.2-.7-.6 0-.6.6 0 1 .6 1.2.8.7 1.2 1.9 1 2.4.7 0-.5.2-.9.5-1-1.8-.3-3.7-1-3.7-4 0-.9.3-1.6.8-2.2 0-.2-.3-1 .1-2 0 0 .7-.3 2.2.7a7.4 7.4 0 0 1 4 0c1.5-1 2.2-.8 2.2-.8.5 1.1.2 2 .1 2.1.5.6.8 1.3.8 2.2 0 3-1.9 3.7-3.6 4 .3.2.5.7.5 1.4v2.2c0 .2.1.5.5.4A8 8 0 0 0 16 8a8 8 0 0 0-8-8z"/></svg></span>Edit on GitHub</a></li>
|
||
</ul>
|
||
</div>
|
||
<hr>
|
||
</header>
|
||
|
||
<div id="toc">
|
||
<h2>Table of Contents</h2>
|
||
<ul>
|
||
<li><span class="stability_2"><a href="#stream_stream">Stream</a></span>
|
||
<ul>
|
||
<li><a href="#stream_organization_of_this_document">Organization of this document</a></li>
|
||
<li><a href="#stream_types_of_streams">Types of streams</a>
|
||
<ul>
|
||
<li><a href="#stream_object_mode">Object mode</a></li>
|
||
<li><a href="#stream_buffering">Buffering</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_api_for_stream_consumers">API for stream consumers</a>
|
||
<ul>
|
||
<li><a href="#stream_writable_streams">Writable streams</a>
|
||
<ul>
|
||
<li><a href="#stream_class_stream_writable">Class: <code>stream.Writable</code></a>
|
||
<ul>
|
||
<li><a href="#stream_event_close">Event: <code>'close'</code></a></li>
|
||
<li><a href="#stream_event_drain">Event: <code>'drain'</code></a></li>
|
||
<li><a href="#stream_event_error">Event: <code>'error'</code></a></li>
|
||
<li><a href="#stream_event_finish">Event: <code>'finish'</code></a></li>
|
||
<li><a href="#stream_event_pipe">Event: <code>'pipe'</code></a></li>
|
||
<li><a href="#stream_event_unpipe">Event: <code>'unpipe'</code></a></li>
|
||
<li><a href="#stream_writable_cork"><code>writable.cork()</code></a></li>
|
||
<li><a href="#stream_writable_destroy_error"><code>writable.destroy([error])</code></a></li>
|
||
<li><a href="#stream_writable_destroyed"><code>writable.destroyed</code></a></li>
|
||
<li><a href="#stream_writable_end_chunk_encoding_callback"><code>writable.end([chunk[, encoding]][, callback])</code></a></li>
|
||
<li><a href="#stream_writable_setdefaultencoding_encoding"><code>writable.setDefaultEncoding(encoding)</code></a></li>
|
||
<li><a href="#stream_writable_uncork"><code>writable.uncork()</code></a></li>
|
||
<li><a href="#stream_writable_writable"><code>writable.writable</code></a></li>
|
||
<li><a href="#stream_writable_writableended"><code>writable.writableEnded</code></a></li>
|
||
<li><a href="#stream_writable_writablecorked"><code>writable.writableCorked</code></a></li>
|
||
<li><a href="#stream_writable_writablefinished"><code>writable.writableFinished</code></a></li>
|
||
<li><a href="#stream_writable_writablehighwatermark"><code>writable.writableHighWaterMark</code></a></li>
|
||
<li><a href="#stream_writable_writablelength"><code>writable.writableLength</code></a></li>
|
||
<li><a href="#stream_writable_writableobjectmode"><code>writable.writableObjectMode</code></a></li>
|
||
<li><a href="#stream_writable_write_chunk_encoding_callback"><code>writable.write(chunk[, encoding][, callback])</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_readable_streams">Readable streams</a>
|
||
<ul>
|
||
<li><a href="#stream_two_reading_modes">Two reading modes</a></li>
|
||
<li><a href="#stream_three_states">Three states</a></li>
|
||
<li><a href="#stream_choose_one_api_style">Choose one API style</a></li>
|
||
<li><a href="#stream_class_stream_readable">Class: <code>stream.Readable</code></a>
|
||
<ul>
|
||
<li><a href="#stream_event_close_1">Event: <code>'close'</code></a></li>
|
||
<li><a href="#stream_event_data">Event: <code>'data'</code></a></li>
|
||
<li><a href="#stream_event_end">Event: <code>'end'</code></a></li>
|
||
<li><a href="#stream_event_error_1">Event: <code>'error'</code></a></li>
|
||
<li><a href="#stream_event_pause">Event: <code>'pause'</code></a></li>
|
||
<li><a href="#stream_event_readable">Event: <code>'readable'</code></a></li>
|
||
<li><a href="#stream_event_resume">Event: <code>'resume'</code></a></li>
|
||
<li><a href="#stream_readable_destroy_error"><code>readable.destroy([error])</code></a></li>
|
||
<li><a href="#stream_readable_destroyed"><code>readable.destroyed</code></a></li>
|
||
<li><a href="#stream_readable_ispaused"><code>readable.isPaused()</code></a></li>
|
||
<li><a href="#stream_readable_pause"><code>readable.pause()</code></a></li>
|
||
<li><a href="#stream_readable_pipe_destination_options"><code>readable.pipe(destination[, options])</code></a></li>
|
||
<li><a href="#stream_readable_read_size"><code>readable.read([size])</code></a></li>
|
||
<li><a href="#stream_readable_readable"><code>readable.readable</code></a></li>
|
||
<li><a href="#stream_readable_readableencoding"><code>readable.readableEncoding</code></a></li>
|
||
<li><a href="#stream_readable_readableended"><code>readable.readableEnded</code></a></li>
|
||
<li><a href="#stream_readable_readableflowing"><code>readable.readableFlowing</code></a></li>
|
||
<li><a href="#stream_readable_readablehighwatermark"><code>readable.readableHighWaterMark</code></a></li>
|
||
<li><a href="#stream_readable_readablelength"><code>readable.readableLength</code></a></li>
|
||
<li><a href="#stream_readable_readableobjectmode"><code>readable.readableObjectMode</code></a></li>
|
||
<li><a href="#stream_readable_resume"><code>readable.resume()</code></a></li>
|
||
<li><a href="#stream_readable_setencoding_encoding"><code>readable.setEncoding(encoding)</code></a></li>
|
||
<li><a href="#stream_readable_unpipe_destination"><code>readable.unpipe([destination])</code></a></li>
|
||
<li><a href="#stream_readable_unshift_chunk_encoding"><code>readable.unshift(chunk[, encoding])</code></a></li>
|
||
<li><a href="#stream_readable_wrap_stream"><code>readable.wrap(stream)</code></a></li>
|
||
<li><a href="#stream_readable_symbol_asynciterator"><code>readable[Symbol.asyncIterator]()</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_duplex_and_transform_streams">Duplex and transform streams</a>
|
||
<ul>
|
||
<li><a href="#stream_class_stream_duplex">Class: <code>stream.Duplex</code></a></li>
|
||
<li><a href="#stream_class_stream_transform">Class: <code>stream.Transform</code></a>
|
||
<ul>
|
||
<li><a href="#stream_transform_destroy_error"><code>transform.destroy([error])</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_stream_finished_stream_options_callback"><code>stream.finished(stream[, options], callback)</code></a></li>
|
||
<li><a href="#stream_stream_pipeline_streams_callback"><code>stream.pipeline(...streams, callback)</code></a></li>
|
||
<li><a href="#stream_stream_readable_from_iterable_options"><code>stream.Readable.from(iterable, [options])</code></a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_api_for_stream_implementers">API for stream implementers</a>
|
||
<ul>
|
||
<li><a href="#stream_simplified_construction">Simplified construction</a></li>
|
||
<li><a href="#stream_implementing_a_writable_stream">Implementing a writable stream</a>
|
||
<ul>
|
||
<li><a href="#stream_new_stream_writable_options"><code>new stream.Writable([options])</code></a></li>
|
||
<li><a href="#stream_writable_write_chunk_encoding_callback_1"><code>writable._write(chunk, encoding, callback)</code></a></li>
|
||
<li><a href="#stream_writable_writev_chunks_callback"><code>writable._writev(chunks, callback)</code></a></li>
|
||
<li><a href="#stream_writable_destroy_err_callback"><code>writable._destroy(err, callback)</code></a></li>
|
||
<li><a href="#stream_writable_final_callback"><code>writable._final(callback)</code></a></li>
|
||
<li><a href="#stream_errors_while_writing">Errors while writing</a></li>
|
||
<li><a href="#stream_an_example_writable_stream">An example writable stream</a></li>
|
||
<li><a href="#stream_decoding_buffers_in_a_writable_stream">Decoding buffers in a writable stream</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_implementing_a_readable_stream">Implementing a readable stream</a>
|
||
<ul>
|
||
<li><a href="#stream_new_stream_readable_options"><code>new stream.Readable([options])</code></a></li>
|
||
<li><a href="#stream_readable_read_size_1"><code>readable._read(size)</code></a></li>
|
||
<li><a href="#stream_readable_destroy_err_callback"><code>readable._destroy(err, callback)</code></a></li>
|
||
<li><a href="#stream_readable_push_chunk_encoding"><code>readable.push(chunk[, encoding])</code></a></li>
|
||
<li><a href="#stream_errors_while_reading">Errors while reading</a></li>
|
||
<li><a href="#stream_an_example_counting_stream">An example counting stream</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_implementing_a_duplex_stream">Implementing a duplex stream</a>
|
||
<ul>
|
||
<li><a href="#stream_new_stream_duplex_options"><code>new stream.Duplex(options)</code></a></li>
|
||
<li><a href="#stream_an_example_duplex_stream">An example duplex stream</a></li>
|
||
<li><a href="#stream_object_mode_duplex_streams">Object mode duplex streams</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_implementing_a_transform_stream">Implementing a transform stream</a>
|
||
<ul>
|
||
<li><a href="#stream_new_stream_transform_options"><code>new stream.Transform([options])</code></a></li>
|
||
<li><a href="#stream_events_finish_and_end">Events: <code>'finish'</code> and <code>'end'</code></a></li>
|
||
<li><a href="#stream_transform_flush_callback"><code>transform._flush(callback)</code></a></li>
|
||
<li><a href="#stream_transform_transform_chunk_encoding_callback"><code>transform._transform(chunk, encoding, callback)</code></a></li>
|
||
<li><a href="#stream_class_stream_passthrough">Class: <code>stream.PassThrough</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_additional_notes">Additional notes</a>
|
||
<ul>
|
||
<li><a href="#stream_streams_compatibility_with_async_generators_and_async_iterators">Streams compatibility with async generators and async iterators</a>
|
||
<ul>
|
||
<li><a href="#stream_consuming_readable_streams_with_async_iterators">Consuming readable streams with async iterators</a></li>
|
||
<li><a href="#stream_creating_readable_streams_with_async_generators">Creating readable streams with async generators</a></li>
|
||
<li><a href="#stream_piping_to_writable_streams_from_async_iterators">Piping to writable streams from async iterators</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#stream_compatibility_with_older_node_js_versions">Compatibility with older Node.js versions</a></li>
|
||
<li><a href="#stream_readable_read_0"><code>readable.read(0)</code></a></li>
|
||
<li><a href="#stream_readable_push"><code>readable.push('')</code></a></li>
|
||
<li><a href="#stream_highwatermark_discrepancy_after_calling_readable_setencoding"><code>highWaterMark</code> discrepancy after calling <code>readable.setEncoding()</code></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div id="apicontent">
|
||
<h1>Stream<a class="srclink" href="https://github.com/nodejs/node/blob/a3d28373d306ed8462a034a8f3019c48354d0cca/lib/stream.js#L30">[src]</a><span><a class="mark" href="#stream_stream" id="stream_stream">#</a></span></h1>
|
||
|
||
<p></p><div class="api_stability api_stability_2"><a href="documentation.html#documentation_stability_index">Stability: 2</a> - Stable</div><p></p>
|
||
<p><strong>Source Code:</strong> <a href="https://github.com/nodejs/node/blob/v12.22.12/lib/stream.js">lib/stream.js</a></p>
|
||
<p>A stream is an abstract interface for working with streaming data in Node.js.
|
||
The <code>stream</code> module provides an API for implementing the stream interface.</p>
|
||
<p>There are many stream objects provided by Node.js. For instance, a
|
||
<a href="http.html#http_class_http_incomingmessage">request to an HTTP server</a> and <a href="process.html#process_process_stdout"><code>process.stdout</code></a>
|
||
are both stream instances.</p>
|
||
<p>Streams can be readable, writable, or both. All streams are instances of
|
||
<a href="events.html#events_class_eventemitter"><code>EventEmitter</code></a>.</p>
|
||
<p>To access the <code>stream</code> module:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> stream = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);</code></pre>
|
||
<p>The <code>stream</code> module is useful for creating new types of stream instances. It is
|
||
usually not necessary to use the <code>stream</code> module to consume streams.</p>
|
||
<h2>Organization of this document<span><a class="mark" href="#stream_organization_of_this_document" id="stream_organization_of_this_document">#</a></span></h2>
|
||
<p>This document contains two primary sections and a third section for notes. The
|
||
first section explains how to use existing streams within an application. The
|
||
second section explains how to create new types of streams.</p>
|
||
<h2>Types of streams<span><a class="mark" href="#stream_types_of_streams" id="stream_types_of_streams">#</a></span></h2>
|
||
<p>There are four fundamental stream types within Node.js:</p>
|
||
<ul>
|
||
<li><a href="#stream_class_stream_writable"><code>Writable</code></a>: streams to which data can be written (for example,
|
||
<a href="fs.html#fs_fs_createwritestream_path_options"><code>fs.createWriteStream()</code></a>).</li>
|
||
<li><a href="#stream_class_stream_readable"><code>Readable</code></a>: streams from which data can be read (for example,
|
||
<a href="fs.html#fs_fs_createreadstream_path_options"><code>fs.createReadStream()</code></a>).</li>
|
||
<li><a href="#stream_class_stream_duplex"><code>Duplex</code></a>: streams that are both <code>Readable</code> and <code>Writable</code> (for example,
|
||
<a href="net.html#net_class_net_socket"><code>net.Socket</code></a>).</li>
|
||
<li><a href="#stream_class_stream_transform"><code>Transform</code></a>: <code>Duplex</code> streams that can modify or transform the data as it
|
||
is written and read (for example, <a href="zlib.html#zlib_zlib_createdeflate_options"><code>zlib.createDeflate()</code></a>).</li>
|
||
</ul>
|
||
<p>Additionally, this module includes the utility functions
|
||
<a href="#stream_stream_pipeline_streams_callback"><code>stream.pipeline()</code></a>, <a href="#stream_stream_finished_stream_options_callback"><code>stream.finished()</code></a> and
|
||
<a href="#stream_stream_readable_from_iterable_options"><code>stream.Readable.from()</code></a>.</p>
|
||
<h3>Object mode<span><a class="mark" href="#stream_object_mode" id="stream_object_mode">#</a></span></h3>
|
||
<p>All streams created by Node.js APIs operate exclusively on strings and <code>Buffer</code>
|
||
(or <code>Uint8Array</code>) objects. It is possible, however, for stream implementations
|
||
to work with other types of JavaScript values (with the exception of <code>null</code>,
|
||
which serves a special purpose within streams). Such streams are considered to
|
||
operate in "object mode".</p>
|
||
<p>Stream instances are switched into object mode using the <code>objectMode</code> option
|
||
when the stream is created. Attempting to switch an existing stream into
|
||
object mode is not safe.</p>
|
||
<h3>Buffering<span><a class="mark" href="#stream_buffering" id="stream_buffering">#</a></span></h3>
|
||
|
||
<p>Both <a href="#stream_class_stream_writable"><code>Writable</code></a> and <a href="#stream_class_stream_readable"><code>Readable</code></a> streams will store data in an internal
|
||
buffer that can be retrieved using <code>writable.writableBuffer</code> or
|
||
<code>readable.readableBuffer</code>, respectively.</p>
|
||
<p>The amount of data potentially buffered depends on the <code>highWaterMark</code> option
|
||
passed into the stream's constructor. For normal streams, the <code>highWaterMark</code>
|
||
option specifies a <a href="#stream_highwatermark_discrepancy_after_calling_readable_setencoding">total number of bytes</a>. For streams operating
|
||
in object mode, the <code>highWaterMark</code> specifies a total number of objects.</p>
|
||
<p>Data is buffered in <code>Readable</code> streams when the implementation calls
|
||
<a href="#stream_readable_push_chunk_encoding"><code>stream.push(chunk)</code></a>. If the consumer of the Stream does not
|
||
call <a href="#stream_readable_read_size"><code>stream.read()</code></a>, the data will sit in the internal
|
||
queue until it is consumed.</p>
|
||
<p>Once the total size of the internal read buffer reaches the threshold specified
|
||
by <code>highWaterMark</code>, the stream will temporarily stop reading data from the
|
||
underlying resource until the data currently buffered can be consumed (that is,
|
||
the stream will stop calling the internal <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> method that is
|
||
used to fill the read buffer).</p>
|
||
<p>Data is buffered in <code>Writable</code> streams when the
|
||
<a href="#stream_writable_write_chunk_encoding_callback"><code>writable.write(chunk)</code></a> method is called repeatedly. While the
|
||
total size of the internal write buffer is below the threshold set by
|
||
<code>highWaterMark</code>, calls to <code>writable.write()</code> will return <code>true</code>. Once
|
||
the size of the internal buffer reaches or exceeds the <code>highWaterMark</code>, <code>false</code>
|
||
will be returned.</p>
|
||
<p>A key goal of the <code>stream</code> API, particularly the <a href="#stream_readable_pipe_destination_options"><code>stream.pipe()</code></a> method,
|
||
is to limit the buffering of data to acceptable levels such that sources and
|
||
destinations of differing speeds will not overwhelm the available memory.</p>
|
||
<p>The <code>highWaterMark</code> option is a threshold, not a limit: it dictates the amount
|
||
of data that a stream buffers before it stops asking for more data. It does not
|
||
enforce a strict memory limitation in general. Specific stream implementations
|
||
may choose to enforce stricter limits but doing so is optional.</p>
|
||
<p>Because <a href="#stream_class_stream_duplex"><code>Duplex</code></a> and <a href="#stream_class_stream_transform"><code>Transform</code></a> streams are both <code>Readable</code> and
|
||
<code>Writable</code>, each maintains <em>two</em> separate internal buffers used for reading and
|
||
writing, allowing each side to operate independently of the other while
|
||
maintaining an appropriate and efficient flow of data. For example,
|
||
<a href="net.html#net_class_net_socket"><code>net.Socket</code></a> instances are <a href="#stream_class_stream_duplex"><code>Duplex</code></a> streams whose <code>Readable</code> side allows
|
||
consumption of data received <em>from</em> the socket and whose <code>Writable</code> side allows
|
||
writing data <em>to</em> the socket. Because data may be written to the socket at a
|
||
faster or slower rate than data is received, each side should
|
||
operate (and buffer) independently of the other.</p>
|
||
<h2>API for stream consumers<span><a class="mark" href="#stream_api_for_stream_consumers" id="stream_api_for_stream_consumers">#</a></span></h2>
|
||
|
||
<p>Almost all Node.js applications, no matter how simple, use streams in some
|
||
manner. The following is an example of using streams in a Node.js application
|
||
that implements an HTTP server:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =></span> {
|
||
<span class="hljs-comment">// `req` is an http.IncomingMessage, which is a readable stream.</span>
|
||
<span class="hljs-comment">// `res` is an http.ServerResponse, which is a writable stream.</span>
|
||
|
||
<span class="hljs-keyword">let</span> body = <span class="hljs-string">''</span>;
|
||
<span class="hljs-comment">// Get the data as utf8 strings.</span>
|
||
<span class="hljs-comment">// If an encoding is not set, Buffer objects will be received.</span>
|
||
req.setEncoding(<span class="hljs-string">'utf8'</span>);
|
||
|
||
<span class="hljs-comment">// Readable streams emit 'data' events once a listener is added.</span>
|
||
req.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
body += chunk;
|
||
});
|
||
|
||
<span class="hljs-comment">// The 'end' event indicates that the entire body has been received.</span>
|
||
req.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-keyword">try</span> {
|
||
<span class="hljs-keyword">const</span> data = <span class="hljs-built_in">JSON</span>.parse(body);
|
||
<span class="hljs-comment">// Write back something interesting to the user:</span>
|
||
res.write(<span class="hljs-keyword">typeof</span> data);
|
||
res.end();
|
||
} <span class="hljs-keyword">catch</span> (er) {
|
||
<span class="hljs-comment">// uh oh! bad json!</span>
|
||
res.statusCode = <span class="hljs-number">400</span>;
|
||
<span class="hljs-keyword">return</span> res.end(<span class="hljs-string">`error: <span class="hljs-subst">${er.message}</span>`</span>);
|
||
}
|
||
});
|
||
});
|
||
|
||
server.listen(<span class="hljs-number">1337</span>);
|
||
|
||
<span class="hljs-comment">// $ curl localhost:1337 -d "{}"</span>
|
||
<span class="hljs-comment">// object</span>
|
||
<span class="hljs-comment">// $ curl localhost:1337 -d "\"foo\""</span>
|
||
<span class="hljs-comment">// string</span>
|
||
<span class="hljs-comment">// $ curl localhost:1337 -d "not json"</span>
|
||
<span class="hljs-comment">// error: Unexpected token o in JSON at position 1</span></code></pre>
|
||
<p><a href="#stream_class_stream_writable"><code>Writable</code></a> streams (such as <code>res</code> in the example) expose methods such as
|
||
<code>write()</code> and <code>end()</code> that are used to write data onto the stream.</p>
|
||
<p><a href="#stream_class_stream_readable"><code>Readable</code></a> streams use the <a href="events.html#events_class_eventemitter"><code>EventEmitter</code></a> API for notifying application
|
||
code when data is available to be read off the stream. That available data can
|
||
be read from the stream in multiple ways.</p>
|
||
<p>Both <a href="#stream_class_stream_writable"><code>Writable</code></a> and <a href="#stream_class_stream_readable"><code>Readable</code></a> streams use the <a href="events.html#events_class_eventemitter"><code>EventEmitter</code></a> API in
|
||
various ways to communicate the current state of the stream.</p>
|
||
<p><a href="#stream_class_stream_duplex"><code>Duplex</code></a> and <a href="#stream_class_stream_transform"><code>Transform</code></a> streams are both <a href="#stream_class_stream_writable"><code>Writable</code></a> and
|
||
<a href="#stream_class_stream_readable"><code>Readable</code></a>.</p>
|
||
<p>Applications that are either writing data to or consuming data from a stream
|
||
are not required to implement the stream interfaces directly and will generally
|
||
have no reason to call <code>require('stream')</code>.</p>
|
||
<p>Developers wishing to implement new types of streams should refer to the
|
||
section <a href="#stream_api_for_stream_implementers">API for stream implementers</a>.</p>
|
||
<h3>Writable streams<span><a class="mark" href="#stream_writable_streams" id="stream_writable_streams">#</a></span></h3>
|
||
<p>Writable streams are an abstraction for a <em>destination</em> to which data is
|
||
written.</p>
|
||
<p>Examples of <a href="#stream_class_stream_writable"><code>Writable</code></a> streams include:</p>
|
||
<ul>
|
||
<li><a href="http.html#http_class_http_clientrequest">HTTP requests, on the client</a></li>
|
||
<li><a href="http.html#http_class_http_serverresponse">HTTP responses, on the server</a></li>
|
||
<li><a href="fs.html#fs_class_fs_writestream">fs write streams</a></li>
|
||
<li><a href="zlib.html">zlib streams</a></li>
|
||
<li><a href="crypto.html">crypto streams</a></li>
|
||
<li><a href="net.html#net_class_net_socket">TCP sockets</a></li>
|
||
<li><a href="child_process.html#child_process_subprocess_stdin">child process stdin</a></li>
|
||
<li><a href="process.html#process_process_stdout"><code>process.stdout</code></a>, <a href="process.html#process_process_stderr"><code>process.stderr</code></a></li>
|
||
</ul>
|
||
<p>Some of these examples are actually <a href="#stream_class_stream_duplex"><code>Duplex</code></a> streams that implement the
|
||
<a href="#stream_class_stream_writable"><code>Writable</code></a> interface.</p>
|
||
<p>All <a href="#stream_class_stream_writable"><code>Writable</code></a> streams implement the interface defined by the
|
||
<code>stream.Writable</code> class.</p>
|
||
<p>While specific instances of <a href="#stream_class_stream_writable"><code>Writable</code></a> streams may differ in various ways,
|
||
all <code>Writable</code> streams follow the same fundamental usage pattern as illustrated
|
||
in the example below:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> myStream = getWritableStreamSomehow();
|
||
myStream.write(<span class="hljs-string">'some data'</span>);
|
||
myStream.write(<span class="hljs-string">'some more data'</span>);
|
||
myStream.end(<span class="hljs-string">'done writing data'</span>);</code></pre>
|
||
<h4>Class: <code>stream.Writable</code><span><a class="mark" href="#stream_class_stream_writable" id="stream_class_stream_writable">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
|
||
<h5>Event: <code>'close'</code><span><a class="mark" href="#stream_event_close" id="stream_event_close">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>Add <code>emitClose</code> option to specify if <code>'close'</code> is emitted on destroy.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<p>The <code>'close'</code> event is emitted when the stream and any of its underlying
|
||
resources (a file descriptor, for example) have been closed. The event indicates
|
||
that no more events will be emitted, and no further computation will occur.</p>
|
||
<p>A <a href="#stream_class_stream_writable"><code>Writable</code></a> stream will always emit the <code>'close'</code> event if it is
|
||
created with the <code>emitClose</code> option.</p>
|
||
<h5>Event: <code>'drain'</code><span><a class="mark" href="#stream_event_drain" id="stream_event_drain">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<p>If a call to <a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write(chunk)</code></a> returns <code>false</code>, the
|
||
<code>'drain'</code> event will be emitted when it is appropriate to resume writing data
|
||
to the stream.</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// Write the data to the supplied writable stream one million times.</span>
|
||
<span class="hljs-comment">// Be attentive to back-pressure.</span>
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">writeOneMillionTimes</span>(<span class="hljs-params">writer, data, encoding, callback</span>) </span>{
|
||
<span class="hljs-keyword">let</span> i = <span class="hljs-number">1000000</span>;
|
||
write();
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">write</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">let</span> ok = <span class="hljs-literal">true</span>;
|
||
<span class="hljs-keyword">do</span> {
|
||
i--;
|
||
<span class="hljs-keyword">if</span> (i === <span class="hljs-number">0</span>) {
|
||
<span class="hljs-comment">// Last time!</span>
|
||
writer.write(data, encoding, callback);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-comment">// See if we should continue, or wait.</span>
|
||
<span class="hljs-comment">// Don't pass the callback, because we're not done yet.</span>
|
||
ok = writer.write(data, encoding);
|
||
}
|
||
} <span class="hljs-keyword">while</span> (i > <span class="hljs-number">0</span> && ok);
|
||
<span class="hljs-keyword">if</span> (i > <span class="hljs-number">0</span>) {
|
||
<span class="hljs-comment">// Had to stop early!</span>
|
||
<span class="hljs-comment">// Write some more once it drains.</span>
|
||
writer.once(<span class="hljs-string">'drain'</span>, write);
|
||
}
|
||
}
|
||
}</code></pre>
|
||
<h5>Event: <code>'error'</code><span><a class="mark" href="#stream_event_error" id="stream_event_error">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a></li>
|
||
</ul>
|
||
<p>The <code>'error'</code> event is emitted if an error occurred while writing or piping
|
||
data. The listener callback is passed a single <code>Error</code> argument when called.</p>
|
||
<p>The stream is not closed when the <code>'error'</code> event is emitted unless the
|
||
<a href="#stream_new_stream_writable_options"><code>autoDestroy</code></a> option was set to <code>true</code> when creating the
|
||
stream.</p>
|
||
<h5>Event: <code>'finish'</code><span><a class="mark" href="#stream_event_finish" id="stream_event_finish">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<p>The <code>'finish'</code> event is emitted after the <a href="#stream_writable_end_chunk_encoding_callback"><code>stream.end()</code></a> method
|
||
has been called, and all data has been flushed to the underlying system.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> writer = getWritableStreamSomehow();
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">100</span>; i++) {
|
||
writer.write(<span class="hljs-string">`hello, #<span class="hljs-subst">${i}</span>!\n`</span>);
|
||
}
|
||
writer.on(<span class="hljs-string">'finish'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'All writes are now complete.'</span>);
|
||
});
|
||
writer.end(<span class="hljs-string">'This is the end\n'</span>);</code></pre>
|
||
<h5>Event: <code>'pipe'</code><span><a class="mark" href="#stream_event_pipe" id="stream_event_pipe">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>src</code> <a href="stream.html#stream_class_stream_readable" class="type"><stream.Readable></a> source stream that is piping to this writable</li>
|
||
</ul>
|
||
<p>The <code>'pipe'</code> event is emitted when the <a href="#stream_readable_pipe_destination_options"><code>stream.pipe()</code></a> method is called on
|
||
a readable stream, adding this writable to its set of destinations.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> writer = getWritableStreamSomehow();
|
||
<span class="hljs-keyword">const</span> reader = getReadableStreamSomehow();
|
||
writer.on(<span class="hljs-string">'pipe'</span>, <span class="hljs-function">(<span class="hljs-params">src</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Something is piping into the writer.'</span>);
|
||
assert.equal(src, reader);
|
||
});
|
||
reader.pipe(writer);</code></pre>
|
||
<h5>Event: <code>'unpipe'</code><span><a class="mark" href="#stream_event_unpipe" id="stream_event_unpipe">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>src</code> <a href="stream.html#stream_class_stream_readable" class="type"><stream.Readable></a> The source stream that
|
||
<a href="#stream_readable_unpipe_destination">unpiped</a> this writable</li>
|
||
</ul>
|
||
<p>The <code>'unpipe'</code> event is emitted when the <a href="#stream_readable_unpipe_destination"><code>stream.unpipe()</code></a> method is called
|
||
on a <a href="#stream_class_stream_readable"><code>Readable</code></a> stream, removing this <a href="#stream_class_stream_writable"><code>Writable</code></a> from its set of
|
||
destinations.</p>
|
||
<p>This is also emitted in case this <a href="#stream_class_stream_writable"><code>Writable</code></a> stream emits an error when a
|
||
<a href="#stream_class_stream_readable"><code>Readable</code></a> stream pipes into it.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> writer = getWritableStreamSomehow();
|
||
<span class="hljs-keyword">const</span> reader = getReadableStreamSomehow();
|
||
writer.on(<span class="hljs-string">'unpipe'</span>, <span class="hljs-function">(<span class="hljs-params">src</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Something has stopped piping into the writer.'</span>);
|
||
assert.equal(src, reader);
|
||
});
|
||
reader.pipe(writer);
|
||
reader.unpipe(writer);</code></pre>
|
||
<h5><code>writable.cork()</code><span><a class="mark" href="#stream_writable_cork" id="stream_writable_cork">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.2</span>
|
||
</div>
|
||
<p>The <code>writable.cork()</code> method forces all written data to be buffered in memory.
|
||
The buffered data will be flushed when either the <a href="#stream_writable_uncork"><code>stream.uncork()</code></a> or
|
||
<a href="#stream_writable_end_chunk_encoding_callback"><code>stream.end()</code></a> methods are called.</p>
|
||
<p>The primary intent of <code>writable.cork()</code> is to accommodate a situation in which
|
||
several small chunks are written to the stream in rapid succession. Instead of
|
||
immediately forwarding them to the underlying destination, <code>writable.cork()</code>
|
||
buffers all the chunks until <code>writable.uncork()</code> is called, which will pass them
|
||
all to <code>writable._writev()</code>, if present. This prevents a head-of-line blocking
|
||
situation where data is being buffered while waiting for the first small chunk
|
||
to be processed. However, use of <code>writable.cork()</code> without implementing
|
||
<code>writable._writev()</code> may have an adverse effect on throughput.</p>
|
||
<p>See also: <a href="#stream_writable_uncork"><code>writable.uncork()</code></a>, <a href="#stream_writable_writev_chunks_callback"><code>writable._writev()</code></a>.</p>
|
||
<h5><code>writable.destroy([error])</code><span><a class="mark" href="#stream_writable_destroy_error" id="stream_writable_destroy_error">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>error</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a> Optional, an error to emit with <code>'error'</code> event.</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>Destroy the stream. Optionally emit an <code>'error'</code> event, and emit a <code>'close'</code>
|
||
event (unless <code>emitClose</code> is set to <code>false</code>). After this call, the writable
|
||
stream has ended and subsequent calls to <code>write()</code> or <code>end()</code> will result in
|
||
an <code>ERR_STREAM_DESTROYED</code> error.
|
||
This is a destructive and immediate way to destroy a stream. Previous calls to
|
||
<code>write()</code> may not have drained, and may trigger an <code>ERR_STREAM_DESTROYED</code> error.
|
||
Use <code>end()</code> instead of destroy if data should flush before close, or wait for
|
||
the <code>'drain'</code> event before destroying the stream.
|
||
Implementors should not override this method,
|
||
but instead implement <a href="#stream_writable_destroy_err_callback"><code>writable._destroy()</code></a>.</p>
|
||
<h5><code>writable.destroyed</code><span><a class="mark" href="#stream_writable_destroyed" id="stream_writable_destroyed">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Is <code>true</code> after <a href="#stream_writable_destroy_error"><code>writable.destroy()</code></a> has been called.</p>
|
||
<h5><code>writable.end([chunk[, encoding]][, callback])</code><span><a class="mark" href="#stream_writable_end_chunk_encoding_callback" id="stream_writable_end_chunk_encoding_callback">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>This method now returns a reference to <code>writable</code>.</p></td></tr>
|
||
<tr><td>v8.0.0</td>
|
||
<td><p>The <code>chunk</code> argument can now be a <code>Uint8Array</code> instance.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array" class="type"><Uint8Array></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> Optional data to write. For streams
|
||
not operating in object mode, <code>chunk</code> must be a string, <code>Buffer</code> or
|
||
<code>Uint8Array</code>. For object mode streams, <code>chunk</code> may be any JavaScript value
|
||
other than <code>null</code>.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The encoding if <code>chunk</code> is a string</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Optional callback for when the stream is finished</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>Calling the <code>writable.end()</code> method signals that no more data will be written
|
||
to the <a href="#stream_class_stream_writable"><code>Writable</code></a>. The optional <code>chunk</code> and <code>encoding</code> arguments allow one
|
||
final additional chunk of data to be written immediately before closing the
|
||
stream. If provided, the optional <code>callback</code> function is attached as a listener
|
||
for the <a href="#stream_event_finish"><code>'finish'</code></a> event.</p>
|
||
<p>Calling the <a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a> method after calling
|
||
<a href="#stream_writable_end_chunk_encoding_callback"><code>stream.end()</code></a> will raise an error.</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// Write 'hello, ' and then end with 'world!'.</span>
|
||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
<span class="hljs-keyword">const</span> file = fs.createWriteStream(<span class="hljs-string">'example.txt'</span>);
|
||
file.write(<span class="hljs-string">'hello, '</span>);
|
||
file.end(<span class="hljs-string">'world!'</span>);
|
||
<span class="hljs-comment">// Writing more now is not allowed!</span></code></pre>
|
||
<h5><code>writable.setDefaultEncoding(encoding)</code><span><a class="mark" href="#stream_writable_setdefaultencoding_encoding" id="stream_writable_setdefaultencoding_encoding">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v6.1.0</td>
|
||
<td><p>This method now returns a reference to <code>writable</code>.</p></td></tr>
|
||
<tr><td>v0.11.15</td>
|
||
<td><p><span>Added in: v0.11.15</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The new default encoding</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>The <code>writable.setDefaultEncoding()</code> method sets the default <code>encoding</code> for a
|
||
<a href="#stream_class_stream_writable"><code>Writable</code></a> stream.</p>
|
||
<h5><code>writable.uncork()</code><span><a class="mark" href="#stream_writable_uncork" id="stream_writable_uncork">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.2</span>
|
||
</div>
|
||
<p>The <code>writable.uncork()</code> method flushes all data buffered since
|
||
<a href="#stream_writable_cork"><code>stream.cork()</code></a> was called.</p>
|
||
<p>When using <a href="#stream_writable_cork"><code>writable.cork()</code></a> and <code>writable.uncork()</code> to manage the buffering
|
||
of writes to a stream, it is recommended that calls to <code>writable.uncork()</code> be
|
||
deferred using <code>process.nextTick()</code>. Doing so allows batching of all
|
||
<code>writable.write()</code> calls that occur within a given Node.js event loop phase.</p>
|
||
<pre><code class="language-js">stream.cork();
|
||
stream.write(<span class="hljs-string">'some '</span>);
|
||
stream.write(<span class="hljs-string">'data '</span>);
|
||
process.nextTick(<span class="hljs-function">() =></span> stream.uncork());</code></pre>
|
||
<p>If the <a href="#stream_writable_cork"><code>writable.cork()</code></a> method is called multiple times on a stream, the
|
||
same number of calls to <code>writable.uncork()</code> must be called to flush the buffered
|
||
data.</p>
|
||
<pre><code class="language-js">stream.cork();
|
||
stream.write(<span class="hljs-string">'some '</span>);
|
||
stream.cork();
|
||
stream.write(<span class="hljs-string">'data '</span>);
|
||
process.nextTick(<span class="hljs-function">() =></span> {
|
||
stream.uncork();
|
||
<span class="hljs-comment">// The data will not be flushed until uncork() is called a second time.</span>
|
||
stream.uncork();
|
||
});</code></pre>
|
||
<p>See also: <a href="#stream_writable_cork"><code>writable.cork()</code></a>.</p>
|
||
<h5><code>writable.writable</code><span><a class="mark" href="#stream_writable_writable" id="stream_writable_writable">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v11.4.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Is <code>true</code> if it is safe to call <a href="#stream_writable_write_chunk_encoding_callback"><code>writable.write()</code></a>.</p>
|
||
<h5><code>writable.writableEnded</code><span><a class="mark" href="#stream_writable_writableended" id="stream_writable_writableended">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.9.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Is <code>true</code> after <a href="#stream_writable_end_chunk_encoding_callback"><code>writable.end()</code></a> has been called. This property
|
||
does not indicate whether the data has been flushed, for this use
|
||
<a href="#stream_writable_writablefinished"><code>writable.writableFinished</code></a> instead.</p>
|
||
<h5><code>writable.writableCorked</code><span><a class="mark" href="#stream_writable_writablecorked" id="stream_writable_writablecorked">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.16.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><integer></a></li>
|
||
</ul>
|
||
<p>Number of times <a href="#stream_writable_uncork"><code>writable.uncork()</code></a> needs to be
|
||
called in order to fully uncork the stream.</p>
|
||
<h5><code>writable.writableFinished</code><span><a class="mark" href="#stream_writable_writablefinished" id="stream_writable_writablefinished">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.6.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Is set to <code>true</code> immediately before the <a href="#stream_event_finish"><code>'finish'</code></a> event is emitted.</p>
|
||
<h5><code>writable.writableHighWaterMark</code><span><a class="mark" href="#stream_writable_writablehighwatermark" id="stream_writable_writablehighwatermark">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v9.3.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a></li>
|
||
</ul>
|
||
<p>Return the value of <code>highWaterMark</code> passed when constructing this
|
||
<code>Writable</code>.</p>
|
||
<h5><code>writable.writableLength</code><span><a class="mark" href="#stream_writable_writablelength" id="stream_writable_writablelength">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v9.4.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a></li>
|
||
</ul>
|
||
<p>This property contains the number of bytes (or objects) in the queue
|
||
ready to be written. The value provides introspection data regarding
|
||
the status of the <code>highWaterMark</code>.</p>
|
||
<h5><code>writable.writableObjectMode</code><span><a class="mark" href="#stream_writable_writableobjectmode" id="stream_writable_writableobjectmode">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.3.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Getter for the property <code>objectMode</code> of a given <code>Writable</code> stream.</p>
|
||
<h5><code>writable.write(chunk[, encoding][, callback])</code><span><a class="mark" href="#stream_writable_write_chunk_encoding_callback" id="stream_writable_write_chunk_encoding_callback">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v8.0.0</td>
|
||
<td><p>The <code>chunk</code> argument can now be a <code>Uint8Array</code> instance.</p></td></tr>
|
||
<tr><td>v6.0.0</td>
|
||
<td><p>Passing <code>null</code> as the <code>chunk</code> parameter will always be considered invalid now, even in object mode.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array" class="type"><Uint8Array></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> Optional data to write. For streams
|
||
not operating in object mode, <code>chunk</code> must be a string, <code>Buffer</code> or
|
||
<code>Uint8Array</code>. For object mode streams, <code>chunk</code> may be any JavaScript value
|
||
other than <code>null</code>.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The encoding, if <code>chunk</code> is a string. <strong>Default:</strong> <code>'utf8'</code></li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Callback for when this chunk of data is flushed</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> <code>false</code> if the stream wishes for the calling code to
|
||
wait for the <code>'drain'</code> event to be emitted before continuing to write
|
||
additional data; otherwise <code>true</code>.</li>
|
||
</ul>
|
||
<p>The <code>writable.write()</code> method writes some data to the stream, and calls the
|
||
supplied <code>callback</code> once the data has been fully handled. If an error
|
||
occurs, the <code>callback</code> <em>may or may not</em> be called with the error as its
|
||
first argument. To reliably detect write errors, add a listener for the
|
||
<code>'error'</code> event.</p>
|
||
<p>The return value is <code>true</code> if the internal buffer is less than the
|
||
<code>highWaterMark</code> configured when the stream was created after admitting <code>chunk</code>.
|
||
If <code>false</code> is returned, further attempts to write data to the stream should
|
||
stop until the <a href="#stream_event_drain"><code>'drain'</code></a> event is emitted.</p>
|
||
<p>While a stream is not draining, calls to <code>write()</code> will buffer <code>chunk</code>, and
|
||
return false. Once all currently buffered chunks are drained (accepted for
|
||
delivery by the operating system), the <code>'drain'</code> event will be emitted.
|
||
It is recommended that once <code>write()</code> returns false, no more chunks be written
|
||
until the <code>'drain'</code> event is emitted. While calling <code>write()</code> on a stream that
|
||
is not draining is allowed, Node.js will buffer all written chunks until
|
||
maximum memory usage occurs, at which point it will abort unconditionally.
|
||
Even before it aborts, high memory usage will cause poor garbage collector
|
||
performance and high RSS (which is not typically released back to the system,
|
||
even after the memory is no longer required). Since TCP sockets may never
|
||
drain if the remote peer does not read the data, writing a socket that is
|
||
not draining may lead to a remotely exploitable vulnerability.</p>
|
||
<p>Writing data while the stream is not draining is particularly
|
||
problematic for a <a href="#stream_class_stream_transform"><code>Transform</code></a>, because the <code>Transform</code> streams are paused
|
||
by default until they are piped or a <code>'data'</code> or <code>'readable'</code> event handler
|
||
is added.</p>
|
||
<p>If the data to be written can be generated or fetched on demand, it is
|
||
recommended to encapsulate the logic into a <a href="#stream_class_stream_readable"><code>Readable</code></a> and use
|
||
<a href="#stream_readable_pipe_destination_options"><code>stream.pipe()</code></a>. However, if calling <code>write()</code> is preferred, it is
|
||
possible to respect backpressure and avoid memory issues using the
|
||
<a href="#stream_event_drain"><code>'drain'</code></a> event:</p>
|
||
<pre><code class="language-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">write</span>(<span class="hljs-params">data, cb</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (!stream.write(data)) {
|
||
stream.once(<span class="hljs-string">'drain'</span>, cb);
|
||
} <span class="hljs-keyword">else</span> {
|
||
process.nextTick(cb);
|
||
}
|
||
}
|
||
|
||
<span class="hljs-comment">// Wait for cb to be called before doing any other write.</span>
|
||
write(<span class="hljs-string">'hello'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Write completed, do more writes now.'</span>);
|
||
});</code></pre>
|
||
<p>A <code>Writable</code> stream in object mode will always ignore the <code>encoding</code> argument.</p>
|
||
<h3>Readable streams<span><a class="mark" href="#stream_readable_streams" id="stream_readable_streams">#</a></span></h3>
|
||
<p>Readable streams are an abstraction for a <em>source</em> from which data is
|
||
consumed.</p>
|
||
<p>Examples of <code>Readable</code> streams include:</p>
|
||
<ul>
|
||
<li><a href="http.html#http_class_http_incomingmessage">HTTP responses, on the client</a></li>
|
||
<li><a href="http.html#http_class_http_incomingmessage">HTTP requests, on the server</a></li>
|
||
<li><a href="fs.html#fs_class_fs_readstream">fs read streams</a></li>
|
||
<li><a href="zlib.html">zlib streams</a></li>
|
||
<li><a href="crypto.html">crypto streams</a></li>
|
||
<li><a href="net.html#net_class_net_socket">TCP sockets</a></li>
|
||
<li><a href="child_process.html#child_process_subprocess_stdout">child process stdout and stderr</a></li>
|
||
<li><a href="process.html#process_process_stdin"><code>process.stdin</code></a></li>
|
||
</ul>
|
||
<p>All <a href="#stream_class_stream_readable"><code>Readable</code></a> streams implement the interface defined by the
|
||
<code>stream.Readable</code> class.</p>
|
||
<h4>Two reading modes<span><a class="mark" href="#stream_two_reading_modes" id="stream_two_reading_modes">#</a></span></h4>
|
||
<p><code>Readable</code> streams effectively operate in one of two modes: flowing and
|
||
paused. These modes are separate from <a href="#stream_object_mode">object mode</a>.
|
||
A <a href="#stream_class_stream_readable"><code>Readable</code></a> stream can be in object mode or not, regardless of whether
|
||
it is in flowing mode or paused mode.</p>
|
||
<ul>
|
||
<li>
|
||
<p>In flowing mode, data is read from the underlying system automatically
|
||
and provided to an application as quickly as possible using events via the
|
||
<a href="events.html#events_class_eventemitter"><code>EventEmitter</code></a> interface.</p>
|
||
</li>
|
||
<li>
|
||
<p>In paused mode, the <a href="#stream_readable_read_size"><code>stream.read()</code></a> method must be called
|
||
explicitly to read chunks of data from the stream.</p>
|
||
</li>
|
||
</ul>
|
||
<p>All <a href="#stream_class_stream_readable"><code>Readable</code></a> streams begin in paused mode but can be switched to flowing
|
||
mode in one of the following ways:</p>
|
||
<ul>
|
||
<li>Adding a <a href="#stream_event_data"><code>'data'</code></a> event handler.</li>
|
||
<li>Calling the <a href="#stream_readable_resume"><code>stream.resume()</code></a> method.</li>
|
||
<li>Calling the <a href="#stream_readable_pipe_destination_options"><code>stream.pipe()</code></a> method to send the data to a <a href="#stream_class_stream_writable"><code>Writable</code></a>.</li>
|
||
</ul>
|
||
<p>The <code>Readable</code> can switch back to paused mode using one of the following:</p>
|
||
<ul>
|
||
<li>If there are no pipe destinations, by calling the
|
||
<a href="#stream_readable_pause"><code>stream.pause()</code></a> method.</li>
|
||
<li>If there are pipe destinations, by removing all pipe destinations.
|
||
Multiple pipe destinations may be removed by calling the
|
||
<a href="#stream_readable_unpipe_destination"><code>stream.unpipe()</code></a> method.</li>
|
||
</ul>
|
||
<p>The important concept to remember is that a <code>Readable</code> will not generate data
|
||
until a mechanism for either consuming or ignoring that data is provided. If
|
||
the consuming mechanism is disabled or taken away, the <code>Readable</code> will <em>attempt</em>
|
||
to stop generating the data.</p>
|
||
<p>For backward compatibility reasons, removing <a href="#stream_event_data"><code>'data'</code></a> event handlers will
|
||
<strong>not</strong> automatically pause the stream. Also, if there are piped destinations,
|
||
then calling <a href="#stream_readable_pause"><code>stream.pause()</code></a> will not guarantee that the
|
||
stream will <em>remain</em> paused once those destinations drain and ask for more data.</p>
|
||
<p>If a <a href="#stream_class_stream_readable"><code>Readable</code></a> is switched into flowing mode and there are no consumers
|
||
available to handle the data, that data will be lost. This can occur, for
|
||
instance, when the <code>readable.resume()</code> method is called without a listener
|
||
attached to the <code>'data'</code> event, or when a <code>'data'</code> event handler is removed
|
||
from the stream.</p>
|
||
<p>Adding a <a href="#stream_event_readable"><code>'readable'</code></a> event handler automatically makes the stream
|
||
stop flowing, and the data has to be consumed via
|
||
<a href="#stream_readable_read_size"><code>readable.read()</code></a>. If the <a href="#stream_event_readable"><code>'readable'</code></a> event handler is
|
||
removed, then the stream will start flowing again if there is a
|
||
<a href="#stream_event_data"><code>'data'</code></a> event handler.</p>
|
||
<h4>Three states<span><a class="mark" href="#stream_three_states" id="stream_three_states">#</a></span></h4>
|
||
<p>The "two modes" of operation for a <code>Readable</code> stream are a simplified
|
||
abstraction for the more complicated internal state management that is happening
|
||
within the <code>Readable</code> stream implementation.</p>
|
||
<p>Specifically, at any given point in time, every <code>Readable</code> is in one of three
|
||
possible states:</p>
|
||
<ul>
|
||
<li><code>readable.readableFlowing === null</code></li>
|
||
<li><code>readable.readableFlowing === false</code></li>
|
||
<li><code>readable.readableFlowing === true</code></li>
|
||
</ul>
|
||
<p>When <code>readable.readableFlowing</code> is <code>null</code>, no mechanism for consuming the
|
||
stream's data is provided. Therefore, the stream will not generate data.
|
||
While in this state, attaching a listener for the <code>'data'</code> event, calling the
|
||
<code>readable.pipe()</code> method, or calling the <code>readable.resume()</code> method will switch
|
||
<code>readable.readableFlowing</code> to <code>true</code>, causing the <code>Readable</code> to begin actively
|
||
emitting events as data is generated.</p>
|
||
<p>Calling <code>readable.pause()</code>, <code>readable.unpipe()</code>, or receiving backpressure
|
||
will cause the <code>readable.readableFlowing</code> to be set as <code>false</code>,
|
||
temporarily halting the flowing of events but <em>not</em> halting the generation of
|
||
data. While in this state, attaching a listener for the <code>'data'</code> event
|
||
will not switch <code>readable.readableFlowing</code> to <code>true</code>.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { PassThrough, Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> pass = <span class="hljs-keyword">new</span> PassThrough();
|
||
<span class="hljs-keyword">const</span> writable = <span class="hljs-keyword">new</span> Writable();
|
||
|
||
pass.pipe(writable);
|
||
pass.unpipe(writable);
|
||
<span class="hljs-comment">// readableFlowing is now false.</span>
|
||
|
||
pass.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> { <span class="hljs-built_in">console</span>.log(chunk.toString()); });
|
||
pass.write(<span class="hljs-string">'ok'</span>); <span class="hljs-comment">// Will not emit 'data'.</span>
|
||
pass.resume(); <span class="hljs-comment">// Must be called to make stream emit 'data'.</span></code></pre>
|
||
<p>While <code>readable.readableFlowing</code> is <code>false</code>, data may be accumulating
|
||
within the stream's internal buffer.</p>
|
||
<h4>Choose one API style<span><a class="mark" href="#stream_choose_one_api_style" id="stream_choose_one_api_style">#</a></span></h4>
|
||
<p>The <code>Readable</code> stream API evolved across multiple Node.js versions and provides
|
||
multiple methods of consuming stream data. In general, developers should choose
|
||
<em>one</em> of the methods of consuming data and <em>should never</em> use multiple methods
|
||
to consume data from a single stream. Specifically, using a combination
|
||
of <code>on('data')</code>, <code>on('readable')</code>, <code>pipe()</code>, or async iterators could
|
||
lead to unintuitive behavior.</p>
|
||
<p>Use of the <code>readable.pipe()</code> method is recommended for most users as it has been
|
||
implemented to provide the easiest way of consuming stream data. Developers that
|
||
require more fine-grained control over the transfer and generation of data can
|
||
use the <a href="events.html#events_class_eventemitter"><code>EventEmitter</code></a> and <code>readable.on('readable')</code>/<code>readable.read()</code>
|
||
or the <code>readable.pause()</code>/<code>readable.resume()</code> APIs.</p>
|
||
<h4>Class: <code>stream.Readable</code><span><a class="mark" href="#stream_class_stream_readable" id="stream_class_stream_readable">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
|
||
<h5>Event: <code>'close'</code><span><a class="mark" href="#stream_event_close_1" id="stream_event_close_1">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>Add <code>emitClose</code> option to specify if <code>'close'</code> is emitted on destroy.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<p>The <code>'close'</code> event is emitted when the stream and any of its underlying
|
||
resources (a file descriptor, for example) have been closed. The event indicates
|
||
that no more events will be emitted, and no further computation will occur.</p>
|
||
<p>A <a href="#stream_class_stream_readable"><code>Readable</code></a> stream will always emit the <code>'close'</code> event if it is
|
||
created with the <code>emitClose</code> option.</p>
|
||
<h5>Event: <code>'data'</code><span><a class="mark" href="#stream_event_data" id="stream_event_data">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> The chunk of data. For streams that are not
|
||
operating in object mode, the chunk will be either a string or <code>Buffer</code>.
|
||
For streams that are in object mode, the chunk can be any JavaScript value
|
||
other than <code>null</code>.</li>
|
||
</ul>
|
||
<p>The <code>'data'</code> event is emitted whenever the stream is relinquishing ownership of
|
||
a chunk of data to a consumer. This may occur whenever the stream is switched
|
||
in flowing mode by calling <code>readable.pipe()</code>, <code>readable.resume()</code>, or by
|
||
attaching a listener callback to the <code>'data'</code> event. The <code>'data'</code> event will
|
||
also be emitted whenever the <code>readable.read()</code> method is called and a chunk of
|
||
data is available to be returned.</p>
|
||
<p>Attaching a <code>'data'</code> event listener to a stream that has not been explicitly
|
||
paused will switch the stream into flowing mode. Data will then be passed as
|
||
soon as it is available.</p>
|
||
<p>The listener callback will be passed the chunk of data as a string if a default
|
||
encoding has been specified for the stream using the
|
||
<code>readable.setEncoding()</code> method; otherwise the data will be passed as a
|
||
<code>Buffer</code>.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
readable.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Received <span class="hljs-subst">${chunk.length}</span> bytes of data.`</span>);
|
||
});</code></pre>
|
||
<h5>Event: <code>'end'</code><span><a class="mark" href="#stream_event_end" id="stream_event_end">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<p>The <code>'end'</code> event is emitted when there is no more data to be consumed from
|
||
the stream.</p>
|
||
<p>The <code>'end'</code> event <strong>will not be emitted</strong> unless the data is completely
|
||
consumed. This can be accomplished by switching the stream into flowing mode,
|
||
or by calling <a href="#stream_readable_read_size"><code>stream.read()</code></a> repeatedly until all data has been
|
||
consumed.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
readable.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Received <span class="hljs-subst">${chunk.length}</span> bytes of data.`</span>);
|
||
});
|
||
readable.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'There will be no more data.'</span>);
|
||
});</code></pre>
|
||
<h5>Event: <code>'error'</code><span><a class="mark" href="#stream_event_error_1" id="stream_event_error_1">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a></li>
|
||
</ul>
|
||
<p>The <code>'error'</code> event may be emitted by a <code>Readable</code> implementation at any time.
|
||
Typically, this may occur if the underlying stream is unable to generate data
|
||
due to an underlying internal failure, or when a stream implementation attempts
|
||
to push an invalid chunk of data.</p>
|
||
<p>The listener callback will be passed a single <code>Error</code> object.</p>
|
||
<h5>Event: <code>'pause'</code><span><a class="mark" href="#stream_event_pause" id="stream_event_pause">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<p>The <code>'pause'</code> event is emitted when <a href="#stream_readable_pause"><code>stream.pause()</code></a> is called
|
||
and <code>readableFlowing</code> is not <code>false</code>.</p>
|
||
<h5>Event: <code>'readable'</code><span><a class="mark" href="#stream_event_readable" id="stream_event_readable">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>The <code>'readable'</code> is always emitted in the next tick after <code>.push()</code> is called.</p></td></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>Using <code>'readable'</code> requires calling <code>.read()</code>.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<p>The <code>'readable'</code> event is emitted when there is data available to be read from
|
||
the stream. In some cases, attaching a listener for the <code>'readable'</code> event will
|
||
cause some amount of data to be read into an internal buffer.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
readable.on(<span class="hljs-string">'readable'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-comment">// There is some data to read now.</span>
|
||
<span class="hljs-keyword">let</span> data;
|
||
|
||
<span class="hljs-keyword">while</span> (data = <span class="hljs-built_in">this</span>.read()) {
|
||
<span class="hljs-built_in">console</span>.log(data);
|
||
}
|
||
});</code></pre>
|
||
<p>The <code>'readable'</code> event will also be emitted once the end of the stream data
|
||
has been reached but before the <code>'end'</code> event is emitted.</p>
|
||
<p>Effectively, the <code>'readable'</code> event indicates that the stream has new
|
||
information: either new data is available or the end of the stream has been
|
||
reached. In the former case, <a href="#stream_readable_read_size"><code>stream.read()</code></a> will return the
|
||
available data. In the latter case, <a href="#stream_readable_read_size"><code>stream.read()</code></a> will return
|
||
<code>null</code>. For instance, in the following example, <code>foo.txt</code> is an empty file:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
<span class="hljs-keyword">const</span> rr = fs.createReadStream(<span class="hljs-string">'foo.txt'</span>);
|
||
rr.on(<span class="hljs-string">'readable'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`readable: <span class="hljs-subst">${rr.read()}</span>`</span>);
|
||
});
|
||
rr.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'end'</span>);
|
||
});</code></pre>
|
||
<p>The output of running this script is:</p>
|
||
<pre><code class="language-console"><span class="hljs-meta">$</span><span class="bash"> node test.js</span>
|
||
readable: null
|
||
end</code></pre>
|
||
<p>In general, the <code>readable.pipe()</code> and <code>'data'</code> event mechanisms are easier to
|
||
understand than the <code>'readable'</code> event. However, handling <code>'readable'</code> might
|
||
result in increased throughput.</p>
|
||
<p>If both <code>'readable'</code> and <a href="#stream_event_data"><code>'data'</code></a> are used at the same time, <code>'readable'</code>
|
||
takes precedence in controlling the flow, i.e. <code>'data'</code> will be emitted
|
||
only when <a href="#stream_readable_read_size"><code>stream.read()</code></a> is called. The
|
||
<code>readableFlowing</code> property would become <code>false</code>.
|
||
If there are <code>'data'</code> listeners when <code>'readable'</code> is removed, the stream
|
||
will start flowing, i.e. <code>'data'</code> events will be emitted without calling
|
||
<code>.resume()</code>.</p>
|
||
<h5>Event: <code>'resume'</code><span><a class="mark" href="#stream_event_resume" id="stream_event_resume">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<p>The <code>'resume'</code> event is emitted when <a href="#stream_readable_resume"><code>stream.resume()</code></a> is
|
||
called and <code>readableFlowing</code> is not <code>true</code>.</p>
|
||
<h5><code>readable.destroy([error])</code><span><a class="mark" href="#stream_readable_destroy_error" id="stream_readable_destroy_error">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>error</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a> Error which will be passed as payload in <code>'error'</code> event</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>Destroy the stream. Optionally emit an <code>'error'</code> event, and emit a <code>'close'</code>
|
||
event (unless <code>emitClose</code> is set to <code>false</code>). After this call, the readable
|
||
stream will release any internal resources and subsequent calls to <code>push()</code>
|
||
will be ignored.
|
||
Implementors should not override this method, but instead implement
|
||
<a href="#stream_readable_destroy_err_callback"><code>readable._destroy()</code></a>.</p>
|
||
<h5><code>readable.destroyed</code><span><a class="mark" href="#stream_readable_destroyed" id="stream_readable_destroyed">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Is <code>true</code> after <a href="#stream_readable_destroy_error"><code>readable.destroy()</code></a> has been called.</p>
|
||
<h5><code>readable.isPaused()</code><span><a class="mark" href="#stream_readable_ispaused" id="stream_readable_ispaused">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.11.14</span>
|
||
</div>
|
||
<ul>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>The <code>readable.isPaused()</code> method returns the current operating state of the
|
||
<code>Readable</code>. This is used primarily by the mechanism that underlies the
|
||
<code>readable.pipe()</code> method. In most typical cases, there will be no reason to
|
||
use this method directly.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = <span class="hljs-keyword">new</span> stream.Readable();
|
||
|
||
readable.isPaused(); <span class="hljs-comment">// === false</span>
|
||
readable.pause();
|
||
readable.isPaused(); <span class="hljs-comment">// === true</span>
|
||
readable.resume();
|
||
readable.isPaused(); <span class="hljs-comment">// === false</span></code></pre>
|
||
<h5><code>readable.pause()</code><span><a class="mark" href="#stream_readable_pause" id="stream_readable_pause">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>The <code>readable.pause()</code> method will cause a stream in flowing mode to stop
|
||
emitting <a href="#stream_event_data"><code>'data'</code></a> events, switching out of flowing mode. Any data that
|
||
becomes available will remain in the internal buffer.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
readable.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Received <span class="hljs-subst">${chunk.length}</span> bytes of data.`</span>);
|
||
readable.pause();
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'There will be no additional data for 1 second.'</span>);
|
||
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Now data will start flowing again.'</span>);
|
||
readable.resume();
|
||
}, <span class="hljs-number">1000</span>);
|
||
});</code></pre>
|
||
<p>The <code>readable.pause()</code> method has no effect if there is a <code>'readable'</code>
|
||
event listener.</p>
|
||
<h5><code>readable.pipe(destination[, options])</code><span><a class="mark" href="#stream_readable_pipe_destination_options" id="stream_readable_pipe_destination_options">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>destination</code> <a href="stream.html#stream_class_stream_writable" class="type"><stream.Writable></a> The destination for writing data</li>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> Pipe options
|
||
<ul>
|
||
<li><code>end</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> End the writer when the reader ends. <strong>Default:</strong> <code>true</code>.</li>
|
||
</ul>
|
||
</li>
|
||
<li>Returns: <a href="stream.html#stream_class_stream_writable" class="type"><stream.Writable></a> The <em>destination</em>, allowing for a chain of pipes if
|
||
it is a <a href="#stream_class_stream_duplex"><code>Duplex</code></a> or a <a href="#stream_class_stream_transform"><code>Transform</code></a> stream</li>
|
||
</ul>
|
||
<p>The <code>readable.pipe()</code> method attaches a <a href="#stream_class_stream_writable"><code>Writable</code></a> stream to the <code>readable</code>,
|
||
causing it to switch automatically into flowing mode and push all of its data
|
||
to the attached <a href="#stream_class_stream_writable"><code>Writable</code></a>. The flow of data will be automatically managed
|
||
so that the destination <code>Writable</code> stream is not overwhelmed by a faster
|
||
<code>Readable</code> stream.</p>
|
||
<p>The following example pipes all of the data from the <code>readable</code> into a file
|
||
named <code>file.txt</code>:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
<span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
<span class="hljs-keyword">const</span> writable = fs.createWriteStream(<span class="hljs-string">'file.txt'</span>);
|
||
<span class="hljs-comment">// All the data from readable goes into 'file.txt'.</span>
|
||
readable.pipe(writable);</code></pre>
|
||
<p>It is possible to attach multiple <code>Writable</code> streams to a single <code>Readable</code>
|
||
stream.</p>
|
||
<p>The <code>readable.pipe()</code> method returns a reference to the <em>destination</em> stream
|
||
making it possible to set up chains of piped streams:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
<span class="hljs-keyword">const</span> r = fs.createReadStream(<span class="hljs-string">'file.txt'</span>);
|
||
<span class="hljs-keyword">const</span> z = zlib.createGzip();
|
||
<span class="hljs-keyword">const</span> w = fs.createWriteStream(<span class="hljs-string">'file.txt.gz'</span>);
|
||
r.pipe(z).pipe(w);</code></pre>
|
||
<p>By default, <a href="#stream_writable_end_chunk_encoding_callback"><code>stream.end()</code></a> is called on the destination <code>Writable</code>
|
||
stream when the source <code>Readable</code> stream emits <a href="#stream_event_end"><code>'end'</code></a>, so that the
|
||
destination is no longer writable. To disable this default behavior, the <code>end</code>
|
||
option can be passed as <code>false</code>, causing the destination stream to remain open:</p>
|
||
<pre><code class="language-js">reader.pipe(writer, { <span class="hljs-attr">end</span>: <span class="hljs-literal">false</span> });
|
||
reader.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
writer.end(<span class="hljs-string">'Goodbye\n'</span>);
|
||
});</code></pre>
|
||
<p>One important caveat is that if the <code>Readable</code> stream emits an error during
|
||
processing, the <code>Writable</code> destination <em>is not closed</em> automatically. If an
|
||
error occurs, it will be necessary to <em>manually</em> close each stream in order
|
||
to prevent memory leaks.</p>
|
||
<p>The <a href="process.html#process_process_stderr"><code>process.stderr</code></a> and <a href="process.html#process_process_stdout"><code>process.stdout</code></a> <code>Writable</code> streams are never
|
||
closed until the Node.js process exits, regardless of the specified options.</p>
|
||
<h5><code>readable.read([size])</code><span><a class="mark" href="#stream_readable_read_size" id="stream_readable_read_size">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>size</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Optional argument to specify how much data to read.</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Null_type" class="type"><null></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a></li>
|
||
</ul>
|
||
<p>The <code>readable.read()</code> method pulls some data out of the internal buffer and
|
||
returns it. If no data available to be read, <code>null</code> is returned. By default,
|
||
the data will be returned as a <code>Buffer</code> object unless an encoding has been
|
||
specified using the <code>readable.setEncoding()</code> method or the stream is operating
|
||
in object mode.</p>
|
||
<p>The optional <code>size</code> argument specifies a specific number of bytes to read. If
|
||
<code>size</code> bytes are not available to be read, <code>null</code> will be returned <em>unless</em>
|
||
the stream has ended, in which case all of the data remaining in the internal
|
||
buffer will be returned.</p>
|
||
<p>If the <code>size</code> argument is not specified, all of the data contained in the
|
||
internal buffer will be returned.</p>
|
||
<p>The <code>size</code> argument must be less than or equal to 1 GB.</p>
|
||
<p>The <code>readable.read()</code> method should only be called on <code>Readable</code> streams
|
||
operating in paused mode. In flowing mode, <code>readable.read()</code> is called
|
||
automatically until the internal buffer is fully drained.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
|
||
<span class="hljs-comment">// 'readable' may be triggered multiple times as data is buffered in</span>
|
||
readable.on(<span class="hljs-string">'readable'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-keyword">let</span> chunk;
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Stream is readable (new data received in buffer)'</span>);
|
||
<span class="hljs-comment">// Use a loop to make sure we read all currently available data</span>
|
||
<span class="hljs-keyword">while</span> (<span class="hljs-literal">null</span> !== (chunk = readable.read())) {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Read <span class="hljs-subst">${chunk.length}</span> bytes of data...`</span>);
|
||
}
|
||
});
|
||
|
||
<span class="hljs-comment">// 'end' will be triggered once when there is no more data available</span>
|
||
readable.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Reached end of stream.'</span>);
|
||
});</code></pre>
|
||
<p>Each call to <code>readable.read()</code> returns a chunk of data, or <code>null</code>. The chunks
|
||
are not concatenated. A <code>while</code> loop is necessary to consume all data
|
||
currently in the buffer. When reading a large file <code>.read()</code> may return <code>null</code>,
|
||
having consumed all buffered content so far, but there is still more data to
|
||
come not yet buffered. In this case a new <code>'readable'</code> event will be emitted
|
||
when there is more data in the buffer. Finally the <code>'end'</code> event will be
|
||
emitted when there is no more data to come.</p>
|
||
<p>Therefore to read a file's whole contents from a <code>readable</code>, it is necessary
|
||
to collect chunks across multiple <code>'readable'</code> events:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> chunks = [];
|
||
|
||
readable.on(<span class="hljs-string">'readable'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-keyword">let</span> chunk;
|
||
<span class="hljs-keyword">while</span> (<span class="hljs-literal">null</span> !== (chunk = readable.read())) {
|
||
chunks.push(chunk);
|
||
}
|
||
});
|
||
|
||
readable.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-keyword">const</span> content = chunks.join(<span class="hljs-string">''</span>);
|
||
});</code></pre>
|
||
<p>A <code>Readable</code> stream in object mode will always return a single item from
|
||
a call to <a href="#stream_readable_read_size"><code>readable.read(size)</code></a>, regardless of the value of the
|
||
<code>size</code> argument.</p>
|
||
<p>If the <code>readable.read()</code> method returns a chunk of data, a <code>'data'</code> event will
|
||
also be emitted.</p>
|
||
<p>Calling <a href="#stream_readable_read_size"><code>stream.read([size])</code></a> after the <a href="#stream_event_end"><code>'end'</code></a> event has
|
||
been emitted will return <code>null</code>. No runtime error will be raised.</p>
|
||
<h5><code>readable.readable</code><span><a class="mark" href="#stream_readable_readable" id="stream_readable_readable">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v11.4.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Is <code>true</code> if it is safe to call <a href="#stream_readable_read_size"><code>readable.read()</code></a>.</p>
|
||
<h5><code>readable.readableEncoding</code><span><a class="mark" href="#stream_readable_readableencoding" id="stream_readable_readableencoding">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.7.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Null_type" class="type"><null></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a></li>
|
||
</ul>
|
||
<p>Getter for the property <code>encoding</code> of a given <code>Readable</code> stream. The <code>encoding</code>
|
||
property can be set using the <a href="#stream_readable_setencoding_encoding"><code>readable.setEncoding()</code></a> method.</p>
|
||
<h5><code>readable.readableEnded</code><span><a class="mark" href="#stream_readable_readableended" id="stream_readable_readableended">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.9.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Becomes <code>true</code> when <a href="#stream_event_end"><code>'end'</code></a> event is emitted.</p>
|
||
<h5><code>readable.readableFlowing</code><span><a class="mark" href="#stream_readable_readableflowing" id="stream_readable_readableflowing">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v9.4.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>This property reflects the current state of a <code>Readable</code> stream as described
|
||
in the <a href="#stream_three_states">Three states</a> section.</p>
|
||
<h5><code>readable.readableHighWaterMark</code><span><a class="mark" href="#stream_readable_readablehighwatermark" id="stream_readable_readablehighwatermark">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v9.3.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a></li>
|
||
</ul>
|
||
<p>Returns the value of <code>highWaterMark</code> passed when constructing this
|
||
<code>Readable</code>.</p>
|
||
<h5><code>readable.readableLength</code><span><a class="mark" href="#stream_readable_readablelength" id="stream_readable_readablelength">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v9.4.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a></li>
|
||
</ul>
|
||
<p>This property contains the number of bytes (or objects) in the queue
|
||
ready to be read. The value provides introspection data regarding
|
||
the status of the <code>highWaterMark</code>.</p>
|
||
<h5><code>readable.readableObjectMode</code><span><a class="mark" href="#stream_readable_readableobjectmode" id="stream_readable_readableobjectmode">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.3.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a></li>
|
||
</ul>
|
||
<p>Getter for the property <code>objectMode</code> of a given <code>Readable</code> stream.</p>
|
||
<h5><code>readable.resume()</code><span><a class="mark" href="#stream_readable_resume" id="stream_readable_resume">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>The <code>resume()</code> has no effect if there is a <code>'readable'</code> event listening.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>The <code>readable.resume()</code> method causes an explicitly paused <code>Readable</code> stream to
|
||
resume emitting <a href="#stream_event_data"><code>'data'</code></a> events, switching the stream into flowing mode.</p>
|
||
<p>The <code>readable.resume()</code> method can be used to fully consume the data from a
|
||
stream without actually processing any of that data:</p>
|
||
<pre><code class="language-js">getReadableStreamSomehow()
|
||
.resume()
|
||
.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Reached the end, but did not read anything.'</span>);
|
||
});</code></pre>
|
||
<p>The <code>readable.resume()</code> method has no effect if there is a <code>'readable'</code>
|
||
event listener.</p>
|
||
<h5><code>readable.setEncoding(encoding)</code><span><a class="mark" href="#stream_readable_setencoding_encoding" id="stream_readable_setencoding_encoding">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The encoding to use.</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>The <code>readable.setEncoding()</code> method sets the character encoding for
|
||
data read from the <code>Readable</code> stream.</p>
|
||
<p>By default, no encoding is assigned and stream data will be returned as
|
||
<code>Buffer</code> objects. Setting an encoding causes the stream data
|
||
to be returned as strings of the specified encoding rather than as <code>Buffer</code>
|
||
objects. For instance, calling <code>readable.setEncoding('utf8')</code> will cause the
|
||
output data to be interpreted as UTF-8 data, and passed as strings. Calling
|
||
<code>readable.setEncoding('hex')</code> will cause the data to be encoded in hexadecimal
|
||
string format.</p>
|
||
<p>The <code>Readable</code> stream will properly handle multi-byte characters delivered
|
||
through the stream that would otherwise become improperly decoded if simply
|
||
pulled from the stream as <code>Buffer</code> objects.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
readable.setEncoding(<span class="hljs-string">'utf8'</span>);
|
||
readable.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
assert.equal(<span class="hljs-keyword">typeof</span> chunk, <span class="hljs-string">'string'</span>);
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Got %d characters of string data:'</span>, chunk.length);
|
||
});</code></pre>
|
||
<h5><code>readable.unpipe([destination])</code><span><a class="mark" href="#stream_readable_unpipe_destination" id="stream_readable_unpipe_destination">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>destination</code> <a href="stream.html#stream_class_stream_writable" class="type"><stream.Writable></a> Optional specific stream to unpipe</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>The <code>readable.unpipe()</code> method detaches a <code>Writable</code> stream previously attached
|
||
using the <a href="#stream_readable_pipe_destination_options"><code>stream.pipe()</code></a> method.</p>
|
||
<p>If the <code>destination</code> is not specified, then <em>all</em> pipes are detached.</p>
|
||
<p>If the <code>destination</code> is specified, but no pipe is set up for it, then
|
||
the method does nothing.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
<span class="hljs-keyword">const</span> readable = getReadableStreamSomehow();
|
||
<span class="hljs-keyword">const</span> writable = fs.createWriteStream(<span class="hljs-string">'file.txt'</span>);
|
||
<span class="hljs-comment">// All the data from readable goes into 'file.txt',</span>
|
||
<span class="hljs-comment">// but only for the first second.</span>
|
||
readable.pipe(writable);
|
||
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Stop writing to file.txt.'</span>);
|
||
readable.unpipe(writable);
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Manually close the file stream.'</span>);
|
||
writable.end();
|
||
}, <span class="hljs-number">1000</span>);</code></pre>
|
||
<h5><code>readable.unshift(chunk[, encoding])</code><span><a class="mark" href="#stream_readable_unshift_chunk_encoding" id="stream_readable_unshift_chunk_encoding">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v8.0.0</td>
|
||
<td><p>The <code>chunk</code> argument can now be a <code>Uint8Array</code> instance.</p></td></tr>
|
||
<tr><td>v0.9.11</td>
|
||
<td><p><span>Added in: v0.9.11</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array" class="type"><Uint8Array></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Null_type" class="type"><null></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> Chunk of data to unshift onto the
|
||
read queue. For streams not operating in object mode, <code>chunk</code> must be a
|
||
string, <code>Buffer</code>, <code>Uint8Array</code> or <code>null</code>. For object mode streams, <code>chunk</code>
|
||
may be any JavaScript value.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> Encoding of string chunks. Must be a valid
|
||
<code>Buffer</code> encoding, such as <code>'utf8'</code> or <code>'ascii'</code>.</li>
|
||
</ul>
|
||
<p>Passing <code>chunk</code> as <code>null</code> signals the end of the stream (EOF) and behaves the
|
||
same as <code>readable.push(null)</code>, after which no more data can be written. The EOF
|
||
signal is put at the end of the buffer and any buffered data will still be
|
||
flushed.</p>
|
||
<p>The <code>readable.unshift()</code> method pushes a chunk of data back into the internal
|
||
buffer. This is useful in certain situations where a stream is being consumed by
|
||
code that needs to "un-consume" some amount of data that it has optimistically
|
||
pulled out of the source, so that the data can be passed on to some other party.</p>
|
||
<p>The <code>stream.unshift(chunk)</code> method cannot be called after the <a href="#stream_event_end"><code>'end'</code></a> event
|
||
has been emitted or a runtime error will be thrown.</p>
|
||
<p>Developers using <code>stream.unshift()</code> often should consider switching to
|
||
use of a <a href="#stream_class_stream_transform"><code>Transform</code></a> stream instead. See the <a href="#stream_api_for_stream_implementers">API for stream implementers</a>
|
||
section for more information.</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// Pull off a header delimited by \n\n.</span>
|
||
<span class="hljs-comment">// Use unshift() if we get too much.</span>
|
||
<span class="hljs-comment">// Call the callback with (error, header, stream).</span>
|
||
<span class="hljs-keyword">const</span> { StringDecoder } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'string_decoder'</span>);
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">parseHeader</span>(<span class="hljs-params">stream, callback</span>) </span>{
|
||
stream.on(<span class="hljs-string">'error'</span>, callback);
|
||
stream.on(<span class="hljs-string">'readable'</span>, onReadable);
|
||
<span class="hljs-keyword">const</span> decoder = <span class="hljs-keyword">new</span> StringDecoder(<span class="hljs-string">'utf8'</span>);
|
||
<span class="hljs-keyword">let</span> header = <span class="hljs-string">''</span>;
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onReadable</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">let</span> chunk;
|
||
<span class="hljs-keyword">while</span> (<span class="hljs-literal">null</span> !== (chunk = stream.read())) {
|
||
<span class="hljs-keyword">const</span> str = decoder.write(chunk);
|
||
<span class="hljs-keyword">if</span> (str.match(<span class="hljs-regexp">/\n\n/</span>)) {
|
||
<span class="hljs-comment">// Found the header boundary.</span>
|
||
<span class="hljs-keyword">const</span> split = str.split(<span class="hljs-regexp">/\n\n/</span>);
|
||
header += split.shift();
|
||
<span class="hljs-keyword">const</span> remaining = split.join(<span class="hljs-string">'\n\n'</span>);
|
||
<span class="hljs-keyword">const</span> buf = Buffer.from(remaining, <span class="hljs-string">'utf8'</span>);
|
||
stream.removeListener(<span class="hljs-string">'error'</span>, callback);
|
||
<span class="hljs-comment">// Remove the 'readable' listener before unshifting.</span>
|
||
stream.removeListener(<span class="hljs-string">'readable'</span>, onReadable);
|
||
<span class="hljs-keyword">if</span> (buf.length)
|
||
stream.unshift(buf);
|
||
<span class="hljs-comment">// Now the body of the message can be read from the stream.</span>
|
||
callback(<span class="hljs-literal">null</span>, header, stream);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-comment">// Still reading the header.</span>
|
||
header += str;
|
||
}
|
||
}
|
||
}
|
||
}</code></pre>
|
||
<p>Unlike <a href="#stream_readable_push_chunk_encoding"><code>stream.push(chunk)</code></a>, <code>stream.unshift(chunk)</code> will not
|
||
end the reading process by resetting the internal reading state of the stream.
|
||
This can cause unexpected results if <code>readable.unshift()</code> is called during a
|
||
read (i.e. from within a <a href="#stream_readable_read_size_1"><code>stream._read()</code></a> implementation on a
|
||
custom stream). Following the call to <code>readable.unshift()</code> with an immediate
|
||
<a href="#stream_readable_push_chunk_encoding"><code>stream.push('')</code></a> will reset the reading state appropriately,
|
||
however it is best to simply avoid calling <code>readable.unshift()</code> while in the
|
||
process of performing a read.</p>
|
||
<h5><code>readable.wrap(stream)</code><span><a class="mark" href="#stream_readable_wrap_stream" id="stream_readable_wrap_stream">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>stream</code> <a href="stream.html#stream_stream" class="type"><Stream></a> An "old style" readable stream</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>Prior to Node.js 0.10, streams did not implement the entire <code>stream</code> module API
|
||
as it is currently defined. (See <a href="#stream_compatibility_with_older_node_js_versions">Compatibility</a> for more information.)</p>
|
||
<p>When using an older Node.js library that emits <a href="#stream_event_data"><code>'data'</code></a> events and has a
|
||
<a href="#stream_readable_pause"><code>stream.pause()</code></a> method that is advisory only, the
|
||
<code>readable.wrap()</code> method can be used to create a <a href="#stream_class_stream_readable"><code>Readable</code></a> stream that uses
|
||
the old stream as its data source.</p>
|
||
<p>It will rarely be necessary to use <code>readable.wrap()</code> but the method has been
|
||
provided as a convenience for interacting with older Node.js applications and
|
||
libraries.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { OldReader } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./old-api-module.js'</span>);
|
||
<span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> oreader = <span class="hljs-keyword">new</span> OldReader();
|
||
<span class="hljs-keyword">const</span> myReader = <span class="hljs-keyword">new</span> Readable().wrap(oreader);
|
||
|
||
myReader.on(<span class="hljs-string">'readable'</span>, <span class="hljs-function">() =></span> {
|
||
myReader.read(); <span class="hljs-comment">// etc.</span>
|
||
});</code></pre>
|
||
<h5><code>readable[Symbol.asyncIterator]()</code><span><a class="mark" href="#stream_readable_symbol_asynciterator" id="stream_readable_symbol_asynciterator">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v11.14.0</td>
|
||
<td><p>Symbol.asyncIterator support is no longer experimental.</p></td></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p><span>Added in: v10.0.0</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li>Returns: <a href="https://tc39.github.io/ecma262/#sec-asynciterator-interface" class="type"><AsyncIterator></a> to fully consume the stream.</li>
|
||
</ul>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
|
||
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">print</span>(<span class="hljs-params">readable</span>) </span>{
|
||
readable.setEncoding(<span class="hljs-string">'utf8'</span>);
|
||
<span class="hljs-keyword">let</span> data = <span class="hljs-string">''</span>;
|
||
<span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">const</span> chunk <span class="hljs-keyword">of</span> readable) {
|
||
data += chunk;
|
||
}
|
||
<span class="hljs-built_in">console</span>.log(data);
|
||
}
|
||
|
||
print(fs.createReadStream(<span class="hljs-string">'file'</span>)).catch(<span class="hljs-built_in">console</span>.error);</code></pre>
|
||
<p>If the loop terminates with a <code>break</code> or a <code>throw</code>, the stream will be
|
||
destroyed. In other terms, iterating over a stream will consume the stream
|
||
fully. The stream will be read in chunks of size equal to the <code>highWaterMark</code>
|
||
option. In the code example above, data will be in a single chunk if the file
|
||
has less then 64KB of data because no <code>highWaterMark</code> option is provided to
|
||
<a href="fs.html#fs_fs_createreadstream_path_options"><code>fs.createReadStream()</code></a>.</p>
|
||
<h3>Duplex and transform streams<span><a class="mark" href="#stream_duplex_and_transform_streams" id="stream_duplex_and_transform_streams">#</a></span></h3>
|
||
<h4>Class: <code>stream.Duplex</code><span><a class="mark" href="#stream_class_stream_duplex" id="stream_class_stream_duplex">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v6.8.0</td>
|
||
<td><p>Instances of <code>Duplex</code> now return <code>true</code> when checking <code>instanceof stream.Writable</code>.</p></td></tr>
|
||
<tr><td>v0.9.4</td>
|
||
<td><p><span>Added in: v0.9.4</span></p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
|
||
<p>Duplex streams are streams that implement both the <a href="#stream_class_stream_readable"><code>Readable</code></a> and
|
||
<a href="#stream_class_stream_writable"><code>Writable</code></a> interfaces.</p>
|
||
<p>Examples of <code>Duplex</code> streams include:</p>
|
||
<ul>
|
||
<li><a href="net.html#net_class_net_socket">TCP sockets</a></li>
|
||
<li><a href="zlib.html">zlib streams</a></li>
|
||
<li><a href="crypto.html">crypto streams</a></li>
|
||
</ul>
|
||
<h4>Class: <code>stream.Transform</code><span><a class="mark" href="#stream_class_stream_transform" id="stream_class_stream_transform">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
|
||
<p>Transform streams are <a href="#stream_class_stream_duplex"><code>Duplex</code></a> streams where the output is in some way
|
||
related to the input. Like all <a href="#stream_class_stream_duplex"><code>Duplex</code></a> streams, <code>Transform</code> streams
|
||
implement both the <a href="#stream_class_stream_readable"><code>Readable</code></a> and <a href="#stream_class_stream_writable"><code>Writable</code></a> interfaces.</p>
|
||
<p>Examples of <code>Transform</code> streams include:</p>
|
||
<ul>
|
||
<li><a href="zlib.html">zlib streams</a></li>
|
||
<li><a href="crypto.html">crypto streams</a></li>
|
||
</ul>
|
||
<h5><code>transform.destroy([error])</code><span><a class="mark" href="#stream_transform_destroy_error" id="stream_transform_destroy_error">#</a></span></h5>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>error</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a></li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" class="type"><this></a></li>
|
||
</ul>
|
||
<p>Destroy the stream, and optionally emit an <code>'error'</code> event. After this call, the
|
||
transform stream would release any internal resources.
|
||
Implementors should not override this method, but instead implement
|
||
<a href="#stream_readable_destroy_err_callback"><code>readable._destroy()</code></a>.
|
||
The default implementation of <code>_destroy()</code> for <code>Transform</code> also emit <code>'close'</code>
|
||
unless <code>emitClose</code> is set in false.</p>
|
||
<h3><code>stream.finished(stream[, options], callback)</code><span><a class="mark" href="#stream_stream_finished_stream_options_callback" id="stream_stream_finished_stream_options_callback">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v10.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>stream</code> <a href="stream.html#stream_stream" class="type"><Stream></a> A readable and/or writable stream.</li>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a>
|
||
<ul>
|
||
<li><code>error</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> If set to <code>false</code>, then a call to <code>emit('error', err)</code> is
|
||
not treated as finished. <strong>Default</strong>: <code>true</code>.</li>
|
||
<li><code>readable</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> When set to <code>false</code>, the callback will be called when
|
||
the stream ends even though the stream might still be readable.
|
||
<strong>Default</strong>: <code>true</code>.</li>
|
||
<li><code>writable</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> When set to <code>false</code>, the callback will be called when
|
||
the stream ends even though the stream might still be writable.
|
||
<strong>Default</strong>: <code>true</code>.</li>
|
||
</ul>
|
||
</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A callback function that takes an optional error
|
||
argument.</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A cleanup function which removes all registered
|
||
listeners.</li>
|
||
</ul>
|
||
<p>A function to get notified when a stream is no longer readable, writable
|
||
or has experienced an error or a premature close event.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { finished } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> rs = fs.createReadStream(<span class="hljs-string">'archive.tar'</span>);
|
||
|
||
finished(rs, <span class="hljs-function">(<span class="hljs-params">err</span>) =></span> {
|
||
<span class="hljs-keyword">if</span> (err) {
|
||
<span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Stream failed.'</span>, err);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Stream is done reading.'</span>);
|
||
}
|
||
});
|
||
|
||
rs.resume(); <span class="hljs-comment">// Drain the stream.</span></code></pre>
|
||
<p>Especially useful in error handling scenarios where a stream is destroyed
|
||
prematurely (like an aborted HTTP request), and will not emit <code>'end'</code>
|
||
or <code>'finish'</code>.</p>
|
||
<p>The <code>finished</code> API is promisify-able as well;</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> finished = util.promisify(stream.finished);
|
||
|
||
<span class="hljs-keyword">const</span> rs = fs.createReadStream(<span class="hljs-string">'archive.tar'</span>);
|
||
|
||
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">await</span> finished(rs);
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Stream is done reading.'</span>);
|
||
}
|
||
|
||
run().catch(<span class="hljs-built_in">console</span>.error);
|
||
rs.resume(); <span class="hljs-comment">// Drain the stream.</span></code></pre>
|
||
<p><code>stream.finished()</code> leaves dangling event listeners (in particular
|
||
<code>'error'</code>, <code>'end'</code>, <code>'finish'</code> and <code>'close'</code>) after <code>callback</code> has been
|
||
invoked. The reason for this is so that unexpected <code>'error'</code> events (due to
|
||
incorrect stream implementations) do not cause unexpected crashes.
|
||
If this is unwanted behavior then the returned cleanup function needs to be
|
||
invoked in the callback:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> cleanup = finished(rs, <span class="hljs-function">(<span class="hljs-params">err</span>) =></span> {
|
||
cleanup();
|
||
<span class="hljs-comment">// ...</span>
|
||
});</code></pre>
|
||
<h3><code>stream.pipeline(...streams, callback)</code><span><a class="mark" href="#stream_stream_pipeline_streams_callback" id="stream_stream_pipeline_streams_callback">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v10.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>...streams</code> <a href="stream.html#stream_stream" class="type"><Stream></a> Two or more streams to pipe between.</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Called when the pipeline is fully done.
|
||
<ul>
|
||
<li><code>err</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<p>A module method to pipe between streams forwarding errors and properly cleaning
|
||
up and provide a callback when the pipeline is complete.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { pipeline } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||
<span class="hljs-keyword">const</span> zlib = <span class="hljs-built_in">require</span>(<span class="hljs-string">'zlib'</span>);
|
||
|
||
<span class="hljs-comment">// Use the pipeline API to easily pipe a series of streams</span>
|
||
<span class="hljs-comment">// together and get notified when the pipeline is fully done.</span>
|
||
|
||
<span class="hljs-comment">// A pipeline to gzip a potentially huge tar file efficiently:</span>
|
||
|
||
pipeline(
|
||
fs.createReadStream(<span class="hljs-string">'archive.tar'</span>),
|
||
zlib.createGzip(),
|
||
fs.createWriteStream(<span class="hljs-string">'archive.tar.gz'</span>),
|
||
<span class="hljs-function">(<span class="hljs-params">err</span>) =></span> {
|
||
<span class="hljs-keyword">if</span> (err) {
|
||
<span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Pipeline failed.'</span>, err);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Pipeline succeeded.'</span>);
|
||
}
|
||
}
|
||
);</code></pre>
|
||
<p>The <code>pipeline</code> API is promisify-able as well:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> pipeline = util.promisify(stream.pipeline);
|
||
|
||
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">run</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">await</span> pipeline(
|
||
fs.createReadStream(<span class="hljs-string">'archive.tar'</span>),
|
||
zlib.createGzip(),
|
||
fs.createWriteStream(<span class="hljs-string">'archive.tar.gz'</span>)
|
||
);
|
||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Pipeline succeeded.'</span>);
|
||
}
|
||
|
||
run().catch(<span class="hljs-built_in">console</span>.error);</code></pre>
|
||
<p><code>stream.pipeline()</code> will call <code>stream.destroy(err)</code> on all streams except:</p>
|
||
<ul>
|
||
<li><code>Readable</code> streams which have emitted <code>'end'</code> or <code>'close'</code>.</li>
|
||
<li><code>Writable</code> streams which have emitted <code>'finish'</code> or <code>'close'</code>.</li>
|
||
</ul>
|
||
<p><code>stream.pipeline()</code> leaves dangling event listeners on the streams
|
||
after the <code>callback</code> has been invoked. In the case of reuse of streams after
|
||
failure, this can cause event listener leaks and swallowed errors.</p>
|
||
<h3><code>stream.Readable.from(iterable, [options])</code><span><a class="mark" href="#stream_stream_readable_from_iterable_options" id="stream_stream_readable_from_iterable_options">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v12.3.0, v10.17.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>iterable</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol" class="type"><Iterable></a> Object implementing the <code>Symbol.asyncIterator</code> or
|
||
<code>Symbol.iterator</code> iterable protocol. Emits an 'error' event if a null
|
||
value is passed.</li>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> Options provided to <code>new stream.Readable([options])</code>.
|
||
By default, <code>Readable.from()</code> will set <code>options.objectMode</code> to <code>true</code>, unless
|
||
this is explicitly opted out by setting <code>options.objectMode</code> to <code>false</code>.</li>
|
||
<li>Returns: <a href="stream.html#stream_class_stream_readable" class="type"><stream.Readable></a></li>
|
||
</ul>
|
||
<p>A utility method for creating readable streams out of iterators.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> * <span class="hljs-title">generate</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">yield</span> <span class="hljs-string">'hello'</span>;
|
||
<span class="hljs-keyword">yield</span> <span class="hljs-string">'streams'</span>;
|
||
}
|
||
|
||
<span class="hljs-keyword">const</span> readable = Readable.from(generate());
|
||
|
||
readable.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(chunk);
|
||
});</code></pre>
|
||
<p>Calling <code>Readable.from(string)</code> or <code>Readable.from(buffer)</code> will not have
|
||
the strings or buffers be iterated to match the other streams semantics
|
||
for performance reasons.</p>
|
||
<h2>API for stream implementers<span><a class="mark" href="#stream_api_for_stream_implementers" id="stream_api_for_stream_implementers">#</a></span></h2>
|
||
|
||
<p>The <code>stream</code> module API has been designed to make it possible to easily
|
||
implement streams using JavaScript's prototypal inheritance model.</p>
|
||
<p>First, a stream developer would declare a new JavaScript class that extends one
|
||
of the four basic stream classes (<code>stream.Writable</code>, <code>stream.Readable</code>,
|
||
<code>stream.Duplex</code>, or <code>stream.Transform</code>), making sure they call the appropriate
|
||
parent class constructor:</p>
|
||
<!-- eslint-disable no-useless-constructor -->
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyWritable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Writable</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>({ highWaterMark, ...options }) {
|
||
<span class="hljs-built_in">super</span>({
|
||
highWaterMark,
|
||
<span class="hljs-attr">autoDestroy</span>: <span class="hljs-literal">true</span>,
|
||
<span class="hljs-attr">emitClose</span>: <span class="hljs-literal">true</span>
|
||
});
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
}</code></pre>
|
||
<p>When extending streams, keep in mind what options the user
|
||
can and should provide before forwarding these to the base constructor. For
|
||
example, if the implementation makes assumptions in regard to the
|
||
<code>autoDestroy</code> and <code>emitClose</code> options, do not allow the
|
||
user to override these. Be explicit about what
|
||
options are forwarded instead of implicitly forwarding all options.</p>
|
||
<p>The new stream class must then implement one or more specific methods, depending
|
||
on the type of stream being created, as detailed in the chart below:</p>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<table><thead><tr><th>Use-case</th><th>Class</th><th>Method(s) to implement</th></tr></thead><tbody><tr><td>Reading only</td><td><a href="#stream_class_stream_readable"><code>Readable</code></a></td><td><a href="#stream_readable_read_size_1"><code>_read()</code></a></td></tr><tr><td>Writing only</td><td><a href="#stream_class_stream_writable"><code>Writable</code></a></td><td><a href="#stream_writable_write_chunk_encoding_callback_1"><code>_write()</code></a>, <a href="#stream_writable_writev_chunks_callback"><code>_writev()</code></a>, <a href="#stream_writable_final_callback"><code>_final()</code></a></td></tr><tr><td>Reading and writing</td><td><a href="#stream_class_stream_duplex"><code>Duplex</code></a></td><td><a href="#stream_readable_read_size_1"><code>_read()</code></a>, <a href="#stream_writable_write_chunk_encoding_callback_1"><code>_write()</code></a>, <a href="#stream_writable_writev_chunks_callback"><code>_writev()</code></a>, <a href="#stream_writable_final_callback"><code>_final()</code></a></td></tr><tr><td>Operate on written data, then read the result</td><td><a href="#stream_class_stream_transform"><code>Transform</code></a></td><td><a href="#stream_transform_transform_chunk_encoding_callback"><code>_transform()</code></a>, <a href="#stream_transform_flush_callback"><code>_flush()</code></a>, <a href="#stream_writable_final_callback"><code>_final()</code></a></td></tr></tbody></table>
|
||
<p>The implementation code for a stream should <em>never</em> call the "public" methods
|
||
of a stream that are intended for use by consumers (as described in the
|
||
<a href="#stream_api_for_stream_consumers">API for stream consumers</a> section). Doing so may lead to adverse side effects
|
||
in application code consuming the stream.</p>
|
||
<p>Avoid overriding public methods such as <code>write()</code>, <code>end()</code>, <code>cork()</code>,
|
||
<code>uncork()</code>, <code>read()</code> and <code>destroy()</code>, or emitting internal events such
|
||
as <code>'error'</code>, <code>'data'</code>, <code>'end'</code>, <code>'finish'</code> and <code>'close'</code> through <code>.emit()</code>.
|
||
Doing so can break current and future stream invariants leading to behavior
|
||
and/or compatibility issues with other streams, stream utilities, and user
|
||
expectations.</p>
|
||
<h3>Simplified construction<span><a class="mark" href="#stream_simplified_construction" id="stream_simplified_construction">#</a></span></h3>
|
||
<div class="api_metadata">
|
||
<span>Added in: v1.2.0</span>
|
||
</div>
|
||
<p>For many simple cases, it is possible to construct a stream without relying on
|
||
inheritance. This can be accomplished by directly creating instances of the
|
||
<code>stream.Writable</code>, <code>stream.Readable</code>, <code>stream.Duplex</code> or <code>stream.Transform</code>
|
||
objects and passing appropriate methods as constructor options.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myWritable = <span class="hljs-keyword">new</span> Writable({
|
||
write(chunk, encoding, callback) {
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
});</code></pre>
|
||
<h3>Implementing a writable stream<span><a class="mark" href="#stream_implementing_a_writable_stream" id="stream_implementing_a_writable_stream">#</a></span></h3>
|
||
<p>The <code>stream.Writable</code> class is extended to implement a <a href="#stream_class_stream_writable"><code>Writable</code></a> stream.</p>
|
||
<p>Custom <code>Writable</code> streams <em>must</em> call the <code>new stream.Writable([options])</code>
|
||
constructor and implement the <code>writable._write()</code> and/or <code>writable._writev()</code>
|
||
method.</p>
|
||
<h4><code>new stream.Writable([options])</code><span><a class="mark" href="#stream_new_stream_writable_options" id="stream_new_stream_writable_options">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v11.2.0</td>
|
||
<td><p>Add <code>autoDestroy</code> option to automatically <code>destroy()</code> the stream when it emits <code>'finish'</code> or errors.</p></td></tr>
|
||
<tr><td>v10.0.0</td>
|
||
<td><p>Add <code>emitClose</code> option to specify if <code>'close'</code> is emitted on destroy.</p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a>
|
||
<ul>
|
||
<li><code>highWaterMark</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Buffer level when
|
||
<a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a> starts returning <code>false</code>. <strong>Default:</strong>
|
||
<code>16384</code> (16KB), or <code>16</code> for <code>objectMode</code> streams.</li>
|
||
<li><code>decodeStrings</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether to encode <code>string</code>s passed to
|
||
<a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a> to <code>Buffer</code>s (with the encoding
|
||
specified in the <a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a> call) before passing
|
||
them to <a href="#stream_writable_write_chunk_encoding_callback_1"><code>stream._write()</code></a>. Other types of data are not
|
||
converted (i.e. <code>Buffer</code>s are not decoded into <code>string</code>s). Setting to
|
||
false will prevent <code>string</code>s from being converted. <strong>Default:</strong> <code>true</code>.</li>
|
||
<li><code>defaultEncoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> The default encoding that is used when no
|
||
encoding is specified as an argument to <a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a>.
|
||
<strong>Default:</strong> <code>'utf8'</code>.</li>
|
||
<li><code>objectMode</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether or not the
|
||
<a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write(anyObj)</code></a> is a valid operation. When set,
|
||
it becomes possible to write JavaScript values other than string,
|
||
<code>Buffer</code> or <code>Uint8Array</code> if supported by the stream implementation.
|
||
<strong>Default:</strong> <code>false</code>.</li>
|
||
<li><code>emitClose</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether or not the stream should emit <code>'close'</code>
|
||
after it has been destroyed. <strong>Default:</strong> <code>true</code>.</li>
|
||
<li><code>write</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the
|
||
<a href="#stream_writable_write_chunk_encoding_callback_1"><code>stream._write()</code></a> method.</li>
|
||
<li><code>writev</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the
|
||
<a href="#stream_writable_writev_chunks_callback"><code>stream._writev()</code></a> method.</li>
|
||
<li><code>destroy</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the
|
||
<a href="#stream_writable_destroy_err_callback"><code>stream._destroy()</code></a> method.</li>
|
||
<li><code>final</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the
|
||
<a href="#stream_writable_final_callback"><code>stream._final()</code></a> method.</li>
|
||
<li><code>autoDestroy</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether this stream should automatically call
|
||
<code>.destroy()</code> on itself after ending. <strong>Default:</strong> <code>false</code>.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<!-- eslint-disable no-useless-constructor -->
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyWritable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Writable</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(options) {
|
||
<span class="hljs-comment">// Calls the stream.Writable() constructor.</span>
|
||
<span class="hljs-built_in">super</span>(options);
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
}</code></pre>
|
||
<p>Or, when using pre-ES6 style constructors:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> util = <span class="hljs-built_in">require</span>(<span class="hljs-string">'util'</span>);
|
||
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyWritable</span>(<span class="hljs-params">options</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (!(<span class="hljs-built_in">this</span> <span class="hljs-keyword">instanceof</span> MyWritable))
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MyWritable(options);
|
||
Writable.call(<span class="hljs-built_in">this</span>, options);
|
||
}
|
||
util.inherits(MyWritable, Writable);</code></pre>
|
||
<p>Or, using the simplified constructor approach:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myWritable = <span class="hljs-keyword">new</span> Writable({
|
||
write(chunk, encoding, callback) {
|
||
<span class="hljs-comment">// ...</span>
|
||
},
|
||
writev(chunks, callback) {
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
});</code></pre>
|
||
<h4><code>writable._write(chunk, encoding, callback)</code><span><a class="mark" href="#stream_writable_write_chunk_encoding_callback_1" id="stream_writable_write_chunk_encoding_callback_1">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v12.11.0</td>
|
||
<td><p>_write() is optional when providing _writev().</p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> The <code>Buffer</code> to be written, converted from the
|
||
<code>string</code> passed to <a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a>. If the stream's
|
||
<code>decodeStrings</code> option is <code>false</code> or the stream is operating in object mode,
|
||
the chunk will not be converted & will be whatever was passed to
|
||
<a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a>.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> If the chunk is a string, then <code>encoding</code> is the
|
||
character encoding of that string. If chunk is a <code>Buffer</code>, or if the
|
||
stream is operating in object mode, <code>encoding</code> may be ignored.</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Call this function (optionally with an error
|
||
argument) when processing is complete for the supplied chunk.</li>
|
||
</ul>
|
||
<p>All <code>Writable</code> stream implementations must provide a
|
||
<a href="#stream_writable_write_chunk_encoding_callback_1"><code>writable._write()</code></a> and/or
|
||
<a href="#stream_writable_writev_chunks_callback"><code>writable._writev()</code></a> method to send data to the underlying
|
||
resource.</p>
|
||
<p><a href="#stream_class_stream_transform"><code>Transform</code></a> streams provide their own implementation of the
|
||
<a href="#stream_writable_write_chunk_encoding_callback_1"><code>writable._write()</code></a>.</p>
|
||
<p>This function MUST NOT be called by application code directly. It should be
|
||
implemented by child classes, and called by the internal <code>Writable</code> class
|
||
methods only.</p>
|
||
<p>The <code>callback</code> method must be called to signal either that the write completed
|
||
successfully or failed with an error. The first argument passed to the
|
||
<code>callback</code> must be the <code>Error</code> object if the call failed or <code>null</code> if the
|
||
write succeeded.</p>
|
||
<p>All calls to <code>writable.write()</code> that occur between the time <code>writable._write()</code>
|
||
is called and the <code>callback</code> is called will cause the written data to be
|
||
buffered. When the <code>callback</code> is invoked, the stream might emit a <a href="#stream_event_drain"><code>'drain'</code></a>
|
||
event. If a stream implementation is capable of processing multiple chunks of
|
||
data at once, the <code>writable._writev()</code> method should be implemented.</p>
|
||
<p>If the <code>decodeStrings</code> property is explicitly set to <code>false</code> in the constructor
|
||
options, then <code>chunk</code> will remain the same object that is passed to <code>.write()</code>,
|
||
and may be a string rather than a <code>Buffer</code>. This is to support implementations
|
||
that have an optimized handling for certain string data encodings. In that case,
|
||
the <code>encoding</code> argument will indicate the character encoding of the string.
|
||
Otherwise, the <code>encoding</code> argument can be safely ignored.</p>
|
||
<p>The <code>writable._write()</code> 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.</p>
|
||
<h4><code>writable._writev(chunks, callback)</code><span><a class="mark" href="#stream_writable_writev_chunks_callback" id="stream_writable_writev_chunks_callback">#</a></span></h4>
|
||
<ul>
|
||
<li><code>chunks</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object[]></a> The chunks to be written. Each chunk has following
|
||
format: <code>{ chunk: ..., encoding: ... }</code>.</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A callback function (optionally with an error
|
||
argument) to be invoked when processing is complete for the supplied chunks.</li>
|
||
</ul>
|
||
<p>This function MUST NOT be called by application code directly. It should be
|
||
implemented by child classes, and called by the internal <code>Writable</code> class
|
||
methods only.</p>
|
||
<p>The <code>writable._writev()</code> method may be implemented in addition or alternatively
|
||
to <code>writable._write()</code> in stream implementations that are capable of processing
|
||
multiple chunks of data at once. If implemented and if there is buffered data
|
||
from previous writes, <code>_writev()</code> will be called instead of <code>_write()</code>.</p>
|
||
<p>The <code>writable._writev()</code> 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.</p>
|
||
<h4><code>writable._destroy(err, callback)</code><span><a class="mark" href="#stream_writable_destroy_err_callback" id="stream_writable_destroy_err_callback">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>err</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a> A possible error.</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A callback function that takes an optional error
|
||
argument.</li>
|
||
</ul>
|
||
<p>The <code>_destroy()</code> method is called by <a href="#stream_writable_destroy_error"><code>writable.destroy()</code></a>.
|
||
It can be overridden by child classes but it <strong>must not</strong> be called directly.</p>
|
||
<h4><code>writable._final(callback)</code><span><a class="mark" href="#stream_writable_final_callback" id="stream_writable_final_callback">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Call this function (optionally with an error
|
||
argument) when finished writing any remaining data.</li>
|
||
</ul>
|
||
<p>The <code>_final()</code> method <strong>must not</strong> be called directly. It may be implemented
|
||
by child classes, and if so, will be called by the internal <code>Writable</code>
|
||
class methods only.</p>
|
||
<p>This optional function will be called before the stream closes, delaying the
|
||
<code>'finish'</code> event until <code>callback</code> is called. This is useful to close resources
|
||
or write buffered data before a stream ends.</p>
|
||
<h4>Errors while writing<span><a class="mark" href="#stream_errors_while_writing" id="stream_errors_while_writing">#</a></span></h4>
|
||
<p>Errors occurring during the processing of the <a href="#stream_writable_write_chunk_encoding_callback_1"><code>writable._write()</code></a>,
|
||
<a href="#stream_writable_writev_chunks_callback"><code>writable._writev()</code></a> and <a href="#stream_writable_final_callback"><code>writable._final()</code></a> methods must be propagated
|
||
by invoking the callback and passing the error as the first argument.
|
||
Throwing an <code>Error</code> from within these methods or manually emitting an <code>'error'</code>
|
||
event results in undefined behavior.</p>
|
||
<p>If a <code>Readable</code> stream pipes into a <code>Writable</code> stream when <code>Writable</code> emits an
|
||
error, the <code>Readable</code> stream will be unpiped.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myWritable = <span class="hljs-keyword">new</span> Writable({
|
||
write(chunk, encoding, callback) {
|
||
<span class="hljs-keyword">if</span> (chunk.toString().indexOf(<span class="hljs-string">'a'</span>) >= <span class="hljs-number">0</span>) {
|
||
callback(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'chunk is invalid'</span>));
|
||
} <span class="hljs-keyword">else</span> {
|
||
callback();
|
||
}
|
||
}
|
||
});</code></pre>
|
||
<h4>An example writable stream<span><a class="mark" href="#stream_an_example_writable_stream" id="stream_an_example_writable_stream">#</a></span></h4>
|
||
<p>The following illustrates a rather simplistic (and somewhat pointless) custom
|
||
<code>Writable</code> stream implementation. While this specific <code>Writable</code> stream instance
|
||
is not of any real particular usefulness, the example illustrates each of the
|
||
required elements of a custom <a href="#stream_class_stream_writable"><code>Writable</code></a> stream instance:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyWritable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Writable</span> </span>{
|
||
_write(chunk, encoding, callback) {
|
||
<span class="hljs-keyword">if</span> (chunk.toString().indexOf(<span class="hljs-string">'a'</span>) >= <span class="hljs-number">0</span>) {
|
||
callback(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'chunk is invalid'</span>));
|
||
} <span class="hljs-keyword">else</span> {
|
||
callback();
|
||
}
|
||
}
|
||
}</code></pre>
|
||
<h4>Decoding buffers in a writable stream<span><a class="mark" href="#stream_decoding_buffers_in_a_writable_stream" id="stream_decoding_buffers_in_a_writable_stream">#</a></span></h4>
|
||
<p>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 <code>StringDecoder</code> and <a href="#stream_class_stream_writable"><code>Writable</code></a>.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Writable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> { StringDecoder } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'string_decoder'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StringWritable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Writable</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(options) {
|
||
<span class="hljs-built_in">super</span>(options);
|
||
<span class="hljs-built_in">this</span>._decoder = <span class="hljs-keyword">new</span> StringDecoder(options && options.defaultEncoding);
|
||
<span class="hljs-built_in">this</span>.data = <span class="hljs-string">''</span>;
|
||
}
|
||
_write(chunk, encoding, callback) {
|
||
<span class="hljs-keyword">if</span> (encoding === <span class="hljs-string">'buffer'</span>) {
|
||
chunk = <span class="hljs-built_in">this</span>._decoder.write(chunk);
|
||
}
|
||
<span class="hljs-built_in">this</span>.data += chunk;
|
||
callback();
|
||
}
|
||
_final(callback) {
|
||
<span class="hljs-built_in">this</span>.data += <span class="hljs-built_in">this</span>._decoder.end();
|
||
callback();
|
||
}
|
||
}
|
||
|
||
<span class="hljs-keyword">const</span> euro = [[<span class="hljs-number">0xE2</span>, <span class="hljs-number">0x82</span>], [<span class="hljs-number">0xAC</span>]].map(Buffer.from);
|
||
<span class="hljs-keyword">const</span> w = <span class="hljs-keyword">new</span> StringWritable();
|
||
|
||
w.write(<span class="hljs-string">'currency: '</span>);
|
||
w.write(euro[<span class="hljs-number">0</span>]);
|
||
w.end(euro[<span class="hljs-number">1</span>]);
|
||
|
||
<span class="hljs-built_in">console</span>.log(w.data); <span class="hljs-comment">// currency: €</span></code></pre>
|
||
<h3>Implementing a readable stream<span><a class="mark" href="#stream_implementing_a_readable_stream" id="stream_implementing_a_readable_stream">#</a></span></h3>
|
||
<p>The <code>stream.Readable</code> class is extended to implement a <a href="#stream_class_stream_readable"><code>Readable</code></a> stream.</p>
|
||
<p>Custom <code>Readable</code> streams <em>must</em> call the <code>new stream.Readable([options])</code>
|
||
constructor and implement the <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> method.</p>
|
||
<h4><code>new stream.Readable([options])</code><span><a class="mark" href="#stream_new_stream_readable_options" id="stream_new_stream_readable_options">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v11.2.0</td>
|
||
<td><p>Add <code>autoDestroy</code> option to automatically <code>destroy()</code> the stream when it emits <code>'end'</code> or errors.</p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a>
|
||
<ul>
|
||
<li><code>highWaterMark</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> The maximum <a href="#stream_highwatermark_discrepancy_after_calling_readable_setencoding">number of bytes</a> to store
|
||
in the internal buffer before ceasing to read from the underlying resource.
|
||
<strong>Default:</strong> <code>16384</code> (16KB), or <code>16</code> for <code>objectMode</code> streams.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> If specified, then buffers will be decoded to
|
||
strings using the specified encoding. <strong>Default:</strong> <code>null</code>.</li>
|
||
<li><code>objectMode</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether this stream should behave
|
||
as a stream of objects. Meaning that <a href="#stream_readable_read_size"><code>stream.read(n)</code></a> returns
|
||
a single value instead of a <code>Buffer</code> of size <code>n</code>. <strong>Default:</strong> <code>false</code>.</li>
|
||
<li><code>emitClose</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether or not the stream should emit <code>'close'</code>
|
||
after it has been destroyed. <strong>Default:</strong> <code>true</code>.</li>
|
||
<li><code>read</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the <a href="#stream_readable_read_size_1"><code>stream._read()</code></a>
|
||
method.</li>
|
||
<li><code>destroy</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the
|
||
<a href="#stream_readable_destroy_err_callback"><code>stream._destroy()</code></a> method.</li>
|
||
<li><code>autoDestroy</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Whether this stream should automatically call
|
||
<code>.destroy()</code> on itself after ending. <strong>Default:</strong> <code>false</code>.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<!-- eslint-disable no-useless-constructor -->
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyReadable</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Readable</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(options) {
|
||
<span class="hljs-comment">// Calls the stream.Readable(options) constructor.</span>
|
||
<span class="hljs-built_in">super</span>(options);
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
}</code></pre>
|
||
<p>Or, when using pre-ES6 style constructors:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> util = <span class="hljs-built_in">require</span>(<span class="hljs-string">'util'</span>);
|
||
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyReadable</span>(<span class="hljs-params">options</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (!(<span class="hljs-built_in">this</span> <span class="hljs-keyword">instanceof</span> MyReadable))
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MyReadable(options);
|
||
Readable.call(<span class="hljs-built_in">this</span>, options);
|
||
}
|
||
util.inherits(MyReadable, Readable);</code></pre>
|
||
<p>Or, using the simplified constructor approach:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myReadable = <span class="hljs-keyword">new</span> Readable({
|
||
read(size) {
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
});</code></pre>
|
||
<h4><code>readable._read(size)</code><span><a class="mark" href="#stream_readable_read_size_1" id="stream_readable_read_size_1">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v0.9.4</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>size</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Number of bytes to read asynchronously</li>
|
||
</ul>
|
||
<p>This function MUST NOT be called by application code directly. It should be
|
||
implemented by child classes, and called by the internal <code>Readable</code> class
|
||
methods only.</p>
|
||
<p>All <code>Readable</code> stream implementations must provide an implementation of the
|
||
<a href="#stream_readable_read_size_1"><code>readable._read()</code></a> method to fetch data from the underlying resource.</p>
|
||
<p>When <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> is called, if data is available from the resource,
|
||
the implementation should begin pushing that data into the read queue using the
|
||
<a href="#stream_readable_push_chunk_encoding"><code>this.push(dataChunk)</code></a> method. <code>_read()</code> should continue reading
|
||
from the resource and pushing data until <code>readable.push()</code> returns <code>false</code>. Only
|
||
when <code>_read()</code> is called again after it has stopped should it resume pushing
|
||
additional data onto the queue.</p>
|
||
<p>Once the <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> method has been called, it will not be called
|
||
again until more data is pushed through the <a href="#stream_readable_push_chunk_encoding"><code>readable.push()</code></a>
|
||
method. Empty data such as empty buffers and strings will not cause
|
||
<a href="#stream_readable_read_size_1"><code>readable._read()</code></a> to be called.</p>
|
||
<p>The <code>size</code> argument is advisory. For implementations where a "read" is a
|
||
single operation that returns data can use the <code>size</code> 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
|
||
<code>size</code> bytes are available before calling <a href="#stream_readable_push_chunk_encoding"><code>stream.push(chunk)</code></a>.</p>
|
||
<p>The <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> 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.</p>
|
||
<h4><code>readable._destroy(err, callback)</code><span><a class="mark" href="#stream_readable_destroy_err_callback" id="stream_readable_destroy_err_callback">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<span>Added in: v8.0.0</span>
|
||
</div>
|
||
<ul>
|
||
<li><code>err</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error" class="type"><Error></a> A possible error.</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A callback function that takes an optional error
|
||
argument.</li>
|
||
</ul>
|
||
<p>The <code>_destroy()</code> method is called by <a href="#stream_readable_destroy_error"><code>readable.destroy()</code></a>.
|
||
It can be overridden by child classes but it <strong>must not</strong> be called directly.</p>
|
||
<h4><code>readable.push(chunk[, encoding])</code><span><a class="mark" href="#stream_readable_push_chunk_encoding" id="stream_readable_push_chunk_encoding">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v8.0.0</td>
|
||
<td><p>The <code>chunk</code> argument can now be a <code>Uint8Array</code> instance.</p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array" class="type"><Uint8Array></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Null_type" class="type"><null></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> Chunk of data to push into the
|
||
read queue. For streams not operating in object mode, <code>chunk</code> must be a
|
||
string, <code>Buffer</code> or <code>Uint8Array</code>. For object mode streams, <code>chunk</code> may be
|
||
any JavaScript value.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> Encoding of string chunks. Must be a valid
|
||
<code>Buffer</code> encoding, such as <code>'utf8'</code> or <code>'ascii'</code>.</li>
|
||
<li>Returns: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> <code>true</code> if additional chunks of data may continue to be
|
||
pushed; <code>false</code> otherwise.</li>
|
||
</ul>
|
||
<p>When <code>chunk</code> is a <code>Buffer</code>, <code>Uint8Array</code> or <code>string</code>, the <code>chunk</code> of data will
|
||
be added to the internal queue for users of the stream to consume.
|
||
Passing <code>chunk</code> as <code>null</code> signals the end of the stream (EOF), after which no
|
||
more data can be written.</p>
|
||
<p>When the <code>Readable</code> is operating in paused mode, the data added with
|
||
<code>readable.push()</code> can be read out by calling the
|
||
<a href="#stream_readable_read_size"><code>readable.read()</code></a> method when the <a href="#stream_event_readable"><code>'readable'</code></a> event is
|
||
emitted.</p>
|
||
<p>When the <code>Readable</code> is operating in flowing mode, the data added with
|
||
<code>readable.push()</code> will be delivered by emitting a <code>'data'</code> event.</p>
|
||
<p>The <code>readable.push()</code> 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 <code>Readable</code> instance:</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// `_source` is an object with readStop() and readStart() methods,</span>
|
||
<span class="hljs-comment">// and an `ondata` member that gets called when it has data, and</span>
|
||
<span class="hljs-comment">// an `onend` member that gets called when the data is over.</span>
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SourceWrapper</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Readable</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(options) {
|
||
<span class="hljs-built_in">super</span>(options);
|
||
|
||
<span class="hljs-built_in">this</span>._source = getLowLevelSourceObject();
|
||
|
||
<span class="hljs-comment">// Every time there's data, push it into the internal buffer.</span>
|
||
<span class="hljs-built_in">this</span>._source.ondata = <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
<span class="hljs-comment">// If push() returns false, then stop reading from source.</span>
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.push(chunk))
|
||
<span class="hljs-built_in">this</span>._source.readStop();
|
||
};
|
||
|
||
<span class="hljs-comment">// When the source ends, push the EOF-signaling `null` chunk.</span>
|
||
<span class="hljs-built_in">this</span>._source.onend = <span class="hljs-function">() =></span> {
|
||
<span class="hljs-built_in">this</span>.push(<span class="hljs-literal">null</span>);
|
||
};
|
||
}
|
||
<span class="hljs-comment">// _read() will be called when the stream wants to pull more data in.</span>
|
||
<span class="hljs-comment">// The advisory size argument is ignored in this case.</span>
|
||
_read(size) {
|
||
<span class="hljs-built_in">this</span>._source.readStart();
|
||
}
|
||
}</code></pre>
|
||
<p>The <code>readable.push()</code> method is used to push the content
|
||
into the internal buffer. It can be driven by the <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> method.</p>
|
||
<p>For streams not operating in object mode, if the <code>chunk</code> parameter of
|
||
<code>readable.push()</code> is <code>undefined</code>, it will be treated as empty string or
|
||
buffer. See <a href="#stream_readable_push"><code>readable.push('')</code></a> for more information.</p>
|
||
<h4>Errors while reading<span><a class="mark" href="#stream_errors_while_reading" id="stream_errors_while_reading">#</a></span></h4>
|
||
<p>Errors occurring during processing of the <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> must be
|
||
propagated through the <a href="#stream_readable_destroy_err_callback"><code>readable.destroy(err)</code></a> method.
|
||
Throwing an <code>Error</code> from within <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> or manually emitting an
|
||
<code>'error'</code> event results in undefined behavior.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myReadable = <span class="hljs-keyword">new</span> Readable({
|
||
read(size) {
|
||
<span class="hljs-keyword">const</span> err = checkSomeErrorCondition();
|
||
<span class="hljs-keyword">if</span> (err) {
|
||
<span class="hljs-built_in">this</span>.destroy(err);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-comment">// Do some work.</span>
|
||
}
|
||
}
|
||
});</code></pre>
|
||
<h4>An example counting stream<span><a class="mark" href="#stream_an_example_counting_stream" id="stream_an_example_counting_stream">#</a></span></h4>
|
||
|
||
<p>The following is a basic example of a <code>Readable</code> stream that emits the numerals
|
||
from 1 to 1,000,000 in ascending order, and then ends.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Counter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Readable</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(opt) {
|
||
<span class="hljs-built_in">super</span>(opt);
|
||
<span class="hljs-built_in">this</span>._max = <span class="hljs-number">1000000</span>;
|
||
<span class="hljs-built_in">this</span>._index = <span class="hljs-number">1</span>;
|
||
}
|
||
|
||
_read() {
|
||
<span class="hljs-keyword">const</span> i = <span class="hljs-built_in">this</span>._index++;
|
||
<span class="hljs-keyword">if</span> (i > <span class="hljs-built_in">this</span>._max)
|
||
<span class="hljs-built_in">this</span>.push(<span class="hljs-literal">null</span>);
|
||
<span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">const</span> str = <span class="hljs-built_in">String</span>(i);
|
||
<span class="hljs-keyword">const</span> buf = Buffer.from(str, <span class="hljs-string">'ascii'</span>);
|
||
<span class="hljs-built_in">this</span>.push(buf);
|
||
}
|
||
}
|
||
}</code></pre>
|
||
<h3>Implementing a duplex stream<span><a class="mark" href="#stream_implementing_a_duplex_stream" id="stream_implementing_a_duplex_stream">#</a></span></h3>
|
||
<p>A <a href="#stream_class_stream_duplex"><code>Duplex</code></a> stream is one that implements both <a href="#stream_class_stream_readable"><code>Readable</code></a> and
|
||
<a href="#stream_class_stream_writable"><code>Writable</code></a>, such as a TCP socket connection.</p>
|
||
<p>Because JavaScript does not have support for multiple inheritance, the
|
||
<code>stream.Duplex</code> class is extended to implement a <a href="#stream_class_stream_duplex"><code>Duplex</code></a> stream (as opposed
|
||
to extending the <code>stream.Readable</code> <em>and</em> <code>stream.Writable</code> classes).</p>
|
||
<p>The <code>stream.Duplex</code> class prototypically inherits from <code>stream.Readable</code> and
|
||
parasitically from <code>stream.Writable</code>, but <code>instanceof</code> will work properly for
|
||
both base classes due to overriding <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance"><code>Symbol.hasInstance</code></a> on
|
||
<code>stream.Writable</code>.</p>
|
||
<p>Custom <code>Duplex</code> streams <em>must</em> call the <code>new stream.Duplex([options])</code>
|
||
constructor and implement <em>both</em> the <a href="#stream_readable_read_size_1"><code>readable._read()</code></a> and
|
||
<code>writable._write()</code> methods.</p>
|
||
<h4><code>new stream.Duplex(options)</code><span><a class="mark" href="#stream_new_stream_duplex_options" id="stream_new_stream_duplex_options">#</a></span></h4>
|
||
<div class="api_metadata">
|
||
<details class="changelog"><summary>History</summary>
|
||
<table>
|
||
<tbody><tr><th>Version</th><th>Changes</th></tr>
|
||
<tr><td>v8.4.0</td>
|
||
<td><p>The <code>readableHighWaterMark</code> and <code>writableHighWaterMark</code> options are supported now.</p></td></tr>
|
||
</tbody></table>
|
||
</details>
|
||
</div>
|
||
<ul>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> Passed to both <code>Writable</code> and <code>Readable</code>
|
||
constructors. Also has the following fields:
|
||
<ul>
|
||
<li><code>allowHalfOpen</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> If set to <code>false</code>, then the stream will
|
||
automatically end the writable side when the readable side ends.
|
||
<strong>Default:</strong> <code>true</code>.</li>
|
||
<li><code>readable</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Sets whether the <code>Duplex</code> should be readable.
|
||
<strong>Default:</strong> <code>true</code>.</li>
|
||
<li><code>writable</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Sets whether the <code>Duplex</code> should be writable.
|
||
<strong>Default:</strong> <code>true</code>.</li>
|
||
<li><code>readableObjectMode</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Sets <code>objectMode</code> for readable side of the
|
||
stream. Has no effect if <code>objectMode</code> is <code>true</code>. <strong>Default:</strong> <code>false</code>.</li>
|
||
<li><code>writableObjectMode</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type" class="type"><boolean></a> Sets <code>objectMode</code> for writable side of the
|
||
stream. Has no effect if <code>objectMode</code> is <code>true</code>. <strong>Default:</strong> <code>false</code>.</li>
|
||
<li><code>readableHighWaterMark</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Sets <code>highWaterMark</code> for the readable side
|
||
of the stream. Has no effect if <code>highWaterMark</code> is provided.</li>
|
||
<li><code>writableHighWaterMark</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type"><number></a> Sets <code>highWaterMark</code> for the writable side
|
||
of the stream. Has no effect if <code>highWaterMark</code> is provided.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<!-- eslint-disable no-useless-constructor -->
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Duplex } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyDuplex</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Duplex</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(options) {
|
||
<span class="hljs-built_in">super</span>(options);
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
}</code></pre>
|
||
<p>Or, when using pre-ES6 style constructors:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Duplex } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> util = <span class="hljs-built_in">require</span>(<span class="hljs-string">'util'</span>);
|
||
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyDuplex</span>(<span class="hljs-params">options</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (!(<span class="hljs-built_in">this</span> <span class="hljs-keyword">instanceof</span> MyDuplex))
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MyDuplex(options);
|
||
Duplex.call(<span class="hljs-built_in">this</span>, options);
|
||
}
|
||
util.inherits(MyDuplex, Duplex);</code></pre>
|
||
<p>Or, using the simplified constructor approach:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Duplex } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myDuplex = <span class="hljs-keyword">new</span> Duplex({
|
||
read(size) {
|
||
<span class="hljs-comment">// ...</span>
|
||
},
|
||
write(chunk, encoding, callback) {
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
});</code></pre>
|
||
<h4>An example duplex stream<span><a class="mark" href="#stream_an_example_duplex_stream" id="stream_an_example_duplex_stream">#</a></span></h4>
|
||
<p>The following illustrates a simple example of a <code>Duplex</code> 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 <code>Duplex</code> stream that buffers
|
||
incoming written data via the <a href="#stream_class_stream_writable"><code>Writable</code></a> interface that is read back out
|
||
via the <a href="#stream_class_stream_readable"><code>Readable</code></a> interface.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Duplex } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> kSource = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'source'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyDuplex</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Duplex</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(source, options) {
|
||
<span class="hljs-built_in">super</span>(options);
|
||
<span class="hljs-built_in">this</span>[kSource] = source;
|
||
}
|
||
|
||
_write(chunk, encoding, callback) {
|
||
<span class="hljs-comment">// The underlying source only deals with strings.</span>
|
||
<span class="hljs-keyword">if</span> (Buffer.isBuffer(chunk))
|
||
chunk = chunk.toString();
|
||
<span class="hljs-built_in">this</span>[kSource].writeSomeData(chunk);
|
||
callback();
|
||
}
|
||
|
||
_read(size) {
|
||
<span class="hljs-built_in">this</span>[kSource].fetchSomeData(size, <span class="hljs-function">(<span class="hljs-params">data, encoding</span>) =></span> {
|
||
<span class="hljs-built_in">this</span>.push(Buffer.from(data, encoding));
|
||
});
|
||
}
|
||
}</code></pre>
|
||
<p>The most important aspect of a <code>Duplex</code> stream is that the <code>Readable</code> and
|
||
<code>Writable</code> sides operate independently of one another despite co-existing within
|
||
a single object instance.</p>
|
||
<h4>Object mode duplex streams<span><a class="mark" href="#stream_object_mode_duplex_streams" id="stream_object_mode_duplex_streams">#</a></span></h4>
|
||
<p>For <code>Duplex</code> streams, <code>objectMode</code> can be set exclusively for either the
|
||
<code>Readable</code> or <code>Writable</code> side using the <code>readableObjectMode</code> and
|
||
<code>writableObjectMode</code> options respectively.</p>
|
||
<p>In the following example, for instance, a new <code>Transform</code> stream (which is a
|
||
type of <a href="#stream_class_stream_duplex"><code>Duplex</code></a> stream) is created that has an object mode <code>Writable</code> side
|
||
that accepts JavaScript numbers that are converted to hexadecimal strings on
|
||
the <code>Readable</code> side.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Transform } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-comment">// All Transform streams are also Duplex Streams.</span>
|
||
<span class="hljs-keyword">const</span> myTransform = <span class="hljs-keyword">new</span> Transform({
|
||
<span class="hljs-attr">writableObjectMode</span>: <span class="hljs-literal">true</span>,
|
||
|
||
transform(chunk, encoding, callback) {
|
||
<span class="hljs-comment">// Coerce the chunk to a number if necessary.</span>
|
||
chunk |= <span class="hljs-number">0</span>;
|
||
|
||
<span class="hljs-comment">// Transform the chunk into something else.</span>
|
||
<span class="hljs-keyword">const</span> data = chunk.toString(<span class="hljs-number">16</span>);
|
||
|
||
<span class="hljs-comment">// Push the data onto the readable queue.</span>
|
||
callback(<span class="hljs-literal">null</span>, <span class="hljs-string">'0'</span>.repeat(data.length % <span class="hljs-number">2</span>) + data);
|
||
}
|
||
});
|
||
|
||
myTransform.setEncoding(<span class="hljs-string">'ascii'</span>);
|
||
myTransform.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> <span class="hljs-built_in">console</span>.log(chunk));
|
||
|
||
myTransform.write(<span class="hljs-number">1</span>);
|
||
<span class="hljs-comment">// Prints: 01</span>
|
||
myTransform.write(<span class="hljs-number">10</span>);
|
||
<span class="hljs-comment">// Prints: 0a</span>
|
||
myTransform.write(<span class="hljs-number">100</span>);
|
||
<span class="hljs-comment">// Prints: 64</span></code></pre>
|
||
<h3>Implementing a transform stream<span><a class="mark" href="#stream_implementing_a_transform_stream" id="stream_implementing_a_transform_stream">#</a></span></h3>
|
||
<p>A <a href="#stream_class_stream_transform"><code>Transform</code></a> stream is a <a href="#stream_class_stream_duplex"><code>Duplex</code></a> stream where the output is computed
|
||
in some way from the input. Examples include <a href="zlib.html">zlib</a> streams or <a href="crypto.html">crypto</a>
|
||
streams that compress, encrypt, or decrypt data.</p>
|
||
<p>There is no requirement that the output be the same size as the input, the same
|
||
number of chunks, or arrive at the same time. For example, a <code>Hash</code> stream will
|
||
only ever have a single chunk of output which is provided when the input is
|
||
ended. A <code>zlib</code> stream will produce output that is either much smaller or much
|
||
larger than its input.</p>
|
||
<p>The <code>stream.Transform</code> class is extended to implement a <a href="#stream_class_stream_transform"><code>Transform</code></a> stream.</p>
|
||
<p>The <code>stream.Transform</code> class prototypically inherits from <code>stream.Duplex</code> and
|
||
implements its own versions of the <code>writable._write()</code> and
|
||
<a href="#stream_readable_read_size_1"><code>readable._read()</code></a> methods. Custom <code>Transform</code> implementations <em>must</em>
|
||
implement the <a href="#stream_transform_transform_chunk_encoding_callback"><code>transform._transform()</code></a> method and <em>may</em>
|
||
also implement the <a href="#stream_transform_flush_callback"><code>transform._flush()</code></a> method.</p>
|
||
<p>Care must be taken when using <code>Transform</code> streams in that data written to the
|
||
stream can cause the <code>Writable</code> side of the stream to become paused if the
|
||
output on the <code>Readable</code> side is not consumed.</p>
|
||
<h4><code>new stream.Transform([options])</code><span><a class="mark" href="#stream_new_stream_transform_options" id="stream_new_stream_transform_options">#</a></span></h4>
|
||
<ul>
|
||
<li><code>options</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object" class="type"><Object></a> Passed to both <code>Writable</code> and <code>Readable</code>
|
||
constructors. Also has the following fields:
|
||
<ul>
|
||
<li><code>transform</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the
|
||
<a href="#stream_transform_transform_chunk_encoding_callback"><code>stream._transform()</code></a> method.</li>
|
||
<li><code>flush</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> Implementation for the <a href="#stream_transform_flush_callback"><code>stream._flush()</code></a>
|
||
method.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
<!-- eslint-disable no-useless-constructor -->
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Transform } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTransform</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Transform</span> </span>{
|
||
<span class="hljs-keyword">constructor</span>(options) {
|
||
<span class="hljs-built_in">super</span>(options);
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
}</code></pre>
|
||
<p>Or, when using pre-ES6 style constructors:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Transform } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
<span class="hljs-keyword">const</span> util = <span class="hljs-built_in">require</span>(<span class="hljs-string">'util'</span>);
|
||
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyTransform</span>(<span class="hljs-params">options</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (!(<span class="hljs-built_in">this</span> <span class="hljs-keyword">instanceof</span> MyTransform))
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MyTransform(options);
|
||
Transform.call(<span class="hljs-built_in">this</span>, options);
|
||
}
|
||
util.inherits(MyTransform, Transform);</code></pre>
|
||
<p>Or, using the simplified constructor approach:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Transform } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">const</span> myTransform = <span class="hljs-keyword">new</span> Transform({
|
||
transform(chunk, encoding, callback) {
|
||
<span class="hljs-comment">// ...</span>
|
||
}
|
||
});</code></pre>
|
||
<h4>Events: <code>'finish'</code> and <code>'end'</code><span><a class="mark" href="#stream_events_finish_and_end" id="stream_events_finish_and_end">#</a></span></h4>
|
||
<p>The <a href="#stream_event_finish"><code>'finish'</code></a> and <a href="#stream_event_end"><code>'end'</code></a> events are from the <code>stream.Writable</code>
|
||
and <code>stream.Readable</code> classes, respectively. The <code>'finish'</code> event is emitted
|
||
after <a href="#stream_writable_end_chunk_encoding_callback"><code>stream.end()</code></a> is called and all chunks have been processed
|
||
by <a href="#stream_transform_transform_chunk_encoding_callback"><code>stream._transform()</code></a>. The <code>'end'</code> event is emitted
|
||
after all data has been output, which occurs after the callback in
|
||
<a href="#stream_transform_flush_callback"><code>transform._flush()</code></a> has been called.</p>
|
||
<h4><code>transform._flush(callback)</code><span><a class="mark" href="#stream_transform_flush_callback" id="stream_transform_flush_callback">#</a></span></h4>
|
||
<ul>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A callback function (optionally with an error
|
||
argument and data) to be called when remaining data has been flushed.</li>
|
||
</ul>
|
||
<p>This function MUST NOT be called by application code directly. It should be
|
||
implemented by child classes, and called by the internal <code>Readable</code> class
|
||
methods only.</p>
|
||
<p>In some cases, a transform operation may need to emit an additional bit of
|
||
data at the end of the stream. For example, a <code>zlib</code> compression stream will
|
||
store an amount of internal state used to optimally compress the output. When
|
||
the stream ends, however, that additional data needs to be flushed so that the
|
||
compressed data will be complete.</p>
|
||
<p>Custom <a href="#stream_class_stream_transform"><code>Transform</code></a> implementations <em>may</em> implement the <code>transform._flush()</code>
|
||
method. This will be called when there is no more written data to be consumed,
|
||
but before the <a href="#stream_event_end"><code>'end'</code></a> event is emitted signaling the end of the
|
||
<a href="#stream_class_stream_readable"><code>Readable</code></a> stream.</p>
|
||
<p>Within the <code>transform._flush()</code> implementation, the <code>transform.push()</code> method
|
||
may be called zero or more times, as appropriate. The <code>callback</code> function must
|
||
be called when the flush operation is complete.</p>
|
||
<p>The <code>transform._flush()</code> 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.</p>
|
||
<h4><code>transform._transform(chunk, encoding, callback)</code><span><a class="mark" href="#stream_transform_transform_chunk_encoding_callback" id="stream_transform_transform_chunk_encoding_callback">#</a></span></h4>
|
||
<ul>
|
||
<li><code>chunk</code> <a href="buffer.html#buffer_class_buffer" class="type"><Buffer></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> | <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types" class="type"><any></a> The <code>Buffer</code> to be transformed, converted from
|
||
the <code>string</code> passed to <a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a>. If the stream's
|
||
<code>decodeStrings</code> option is <code>false</code> or the stream is operating in object mode,
|
||
the chunk will not be converted & will be whatever was passed to
|
||
<a href="#stream_writable_write_chunk_encoding_callback"><code>stream.write()</code></a>.</li>
|
||
<li><code>encoding</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type" class="type"><string></a> If the chunk is a string, then this is the
|
||
encoding type. If chunk is a buffer, then this is the special
|
||
value <code>'buffer'</code>. Ignore it in that case.</li>
|
||
<li><code>callback</code> <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type"><Function></a> A callback function (optionally with an error
|
||
argument and data) to be called after the supplied <code>chunk</code> has been
|
||
processed.</li>
|
||
</ul>
|
||
<p>This function MUST NOT be called by application code directly. It should be
|
||
implemented by child classes, and called by the internal <code>Readable</code> class
|
||
methods only.</p>
|
||
<p>All <code>Transform</code> stream implementations must provide a <code>_transform()</code>
|
||
method to accept input and produce output. The <code>transform._transform()</code>
|
||
implementation handles the bytes being written, computes an output, then passes
|
||
that output off to the readable portion using the <code>transform.push()</code> method.</p>
|
||
<p>The <code>transform.push()</code> method may be called zero or more times to generate
|
||
output from a single input chunk, depending on how much is to be output
|
||
as a result of the chunk.</p>
|
||
<p>It is possible that no output is generated from any given chunk of input data.</p>
|
||
<p>The <code>callback</code> function must be called only when the current chunk is completely
|
||
consumed. The first argument passed to the <code>callback</code> must be an <code>Error</code> object
|
||
if an error occurred while processing the input or <code>null</code> otherwise. If a second
|
||
argument is passed to the <code>callback</code>, it will be forwarded on to the
|
||
<code>transform.push()</code> method. In other words, the following are equivalent:</p>
|
||
<pre><code class="language-js">transform.prototype._transform = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data, encoding, callback</span>) </span>{
|
||
<span class="hljs-built_in">this</span>.push(data);
|
||
callback();
|
||
};
|
||
|
||
transform.prototype._transform = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">data, encoding, callback</span>) </span>{
|
||
callback(<span class="hljs-literal">null</span>, data);
|
||
};</code></pre>
|
||
<p>The <code>transform._transform()</code> 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.</p>
|
||
<p><code>transform._transform()</code> is never called in parallel; streams implement a
|
||
queue mechanism, and to receive the next chunk, <code>callback</code> must be
|
||
called, either synchronously or asynchronously.</p>
|
||
<h4>Class: <code>stream.PassThrough</code><span><a class="mark" href="#stream_class_stream_passthrough" id="stream_class_stream_passthrough">#</a></span></h4>
|
||
<p>The <code>stream.PassThrough</code> class is a trivial implementation of a <a href="#stream_class_stream_transform"><code>Transform</code></a>
|
||
stream that simply passes the input bytes across to the output. Its purpose is
|
||
primarily for examples and testing, but there are some use cases where
|
||
<code>stream.PassThrough</code> is useful as a building block for novel sorts of streams.</p>
|
||
<h2>Additional notes<span><a class="mark" href="#stream_additional_notes" id="stream_additional_notes">#</a></span></h2>
|
||
|
||
<h3>Streams compatibility with async generators and async iterators<span><a class="mark" href="#stream_streams_compatibility_with_async_generators_and_async_iterators" id="stream_streams_compatibility_with_async_generators_and_async_iterators">#</a></span></h3>
|
||
<p>With the support of async generators and iterators in JavaScript, async
|
||
generators are effectively a first-class language-level stream construct at
|
||
this point.</p>
|
||
<p>Some common interop cases of using Node.js streams with async generators
|
||
and async iterators are provided below.</p>
|
||
<h4>Consuming readable streams with async iterators<span><a class="mark" href="#stream_consuming_readable_streams_with_async_iterators" id="stream_consuming_readable_streams_with_async_iterators">#</a></span></h4>
|
||
<pre><code class="language-js">(<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">const</span> chunk <span class="hljs-keyword">of</span> readable) {
|
||
<span class="hljs-built_in">console</span>.log(chunk);
|
||
}
|
||
})();</code></pre>
|
||
<p>Async iterators register a permanent error handler on the stream to prevent any
|
||
unhandled post-destroy errors.</p>
|
||
<h4>Creating readable streams with async generators<span><a class="mark" href="#stream_creating_readable_streams_with_async_generators" id="stream_creating_readable_streams_with_async_generators">#</a></span></h4>
|
||
<p>We can construct a Node.js readable stream from an asynchronous generator
|
||
using the <code>Readable.from()</code> utility method:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { Readable } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'stream'</span>);
|
||
|
||
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> * <span class="hljs-title">generate</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">yield</span> <span class="hljs-string">'a'</span>;
|
||
<span class="hljs-keyword">yield</span> <span class="hljs-string">'b'</span>;
|
||
<span class="hljs-keyword">yield</span> <span class="hljs-string">'c'</span>;
|
||
}
|
||
|
||
<span class="hljs-keyword">const</span> readable = Readable.from(generate());
|
||
|
||
readable.on(<span class="hljs-string">'data'</span>, <span class="hljs-function">(<span class="hljs-params">chunk</span>) =></span> {
|
||
<span class="hljs-built_in">console</span>.log(chunk);
|
||
});</code></pre>
|
||
<h4>Piping to writable streams from async iterators<span><a class="mark" href="#stream_piping_to_writable_streams_from_async_iterators" id="stream_piping_to_writable_streams_from_async_iterators">#</a></span></h4>
|
||
<p>In the scenario of writing to a writable stream from an async iterator, ensure
|
||
the correct handling of backpressure and errors.</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> { once } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'events'</span>);
|
||
<span class="hljs-keyword">const</span> finished = util.promisify(stream.finished);
|
||
|
||
<span class="hljs-keyword">const</span> writable = fs.createWriteStream(<span class="hljs-string">'./file'</span>);
|
||
|
||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">drain</span>(<span class="hljs-params">writable</span>) </span>{
|
||
<span class="hljs-keyword">if</span> (writable.destroyed) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.reject(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'premature close'</span>));
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.race([
|
||
once(writable, <span class="hljs-string">'drain'</span>),
|
||
once(writable, <span class="hljs-string">'close'</span>)
|
||
.then(<span class="hljs-function">() =></span> <span class="hljs-built_in">Promise</span>.reject(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'premature close'</span>)))
|
||
]);
|
||
}
|
||
|
||
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pump</span>(<span class="hljs-params">iterable, writable</span>) </span>{
|
||
<span class="hljs-keyword">for</span> <span class="hljs-keyword">await</span> (<span class="hljs-keyword">const</span> chunk <span class="hljs-keyword">of</span> iterable) {
|
||
<span class="hljs-comment">// Handle backpressure on write().</span>
|
||
<span class="hljs-keyword">if</span> (!writable.write(chunk)) {
|
||
<span class="hljs-keyword">await</span> drain(writable);
|
||
}
|
||
}
|
||
writable.end();
|
||
}
|
||
|
||
(<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-comment">// Ensure completion without errors.</span>
|
||
<span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all([
|
||
pump(iterable, writable),
|
||
finished(writable)
|
||
]);
|
||
})();</code></pre>
|
||
<p>In the above, errors on <code>write()</code> would be caught and thrown by the
|
||
<code>once()</code> listener for the <code>'drain'</code> event, since <code>once()</code> will also handle the
|
||
<code>'error'</code> event. To ensure completion of the write stream without errors,
|
||
it is safer to use the <code>finished()</code> method as above, instead of using the
|
||
<code>once()</code> listener for the <code>'finish'</code> event. Under certain cases, an <code>'error'</code>
|
||
event could be emitted by the writable stream after <code>'finish'</code> and as <code>once()</code>
|
||
will release the <code>'error'</code> handler on handling the <code>'finish'</code> event, it could
|
||
result in an unhandled error.</p>
|
||
<p>Alternatively, the readable stream could be wrapped with <code>Readable.from()</code> and
|
||
then piped via <code>.pipe()</code>:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> finished = util.promisify(stream.finished);
|
||
|
||
<span class="hljs-keyword">const</span> writable = fs.createWriteStream(<span class="hljs-string">'./file'</span>);
|
||
|
||
(<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">const</span> readable = Readable.from(iterable);
|
||
readable.pipe(writable);
|
||
<span class="hljs-comment">// Ensure completion without errors.</span>
|
||
<span class="hljs-keyword">await</span> finished(writable);
|
||
})();</code></pre>
|
||
<p>Or, using <code>stream.pipeline()</code> to pipe streams:</p>
|
||
<pre><code class="language-js"><span class="hljs-keyword">const</span> pipeline = util.promisify(stream.pipeline);
|
||
|
||
<span class="hljs-keyword">const</span> writable = fs.createWriteStream(<span class="hljs-string">'./file'</span>);
|
||
|
||
(<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
|
||
<span class="hljs-keyword">const</span> readable = Readable.from(iterable);
|
||
<span class="hljs-keyword">await</span> pipeline(readable, writable);
|
||
})();</code></pre>
|
||
|
||
<h3>Compatibility with older Node.js versions<span><a class="mark" href="#stream_compatibility_with_older_node_js_versions" id="stream_compatibility_with_older_node_js_versions">#</a></span></h3>
|
||
|
||
<p>Prior to Node.js 0.10, the <code>Readable</code> stream interface was simpler, but also
|
||
less powerful and less useful.</p>
|
||
<ul>
|
||
<li>Rather than waiting for calls to the <a href="#stream_readable_read_size"><code>stream.read()</code></a> method,
|
||
<a href="#stream_event_data"><code>'data'</code></a> events would begin emitting immediately. Applications that
|
||
would need to perform some amount of work to decide how to handle data
|
||
were required to store read data into buffers so the data would not be lost.</li>
|
||
<li>The <a href="#stream_readable_pause"><code>stream.pause()</code></a> method was advisory, rather than
|
||
guaranteed. This meant that it was still necessary to be prepared to receive
|
||
<a href="#stream_event_data"><code>'data'</code></a> events <em>even when the stream was in a paused state</em>.</li>
|
||
</ul>
|
||
<p>In Node.js 0.10, the <a href="#stream_class_stream_readable"><code>Readable</code></a> class was added. For backward
|
||
compatibility with older Node.js programs, <code>Readable</code> streams switch into
|
||
"flowing mode" when a <a href="#stream_event_data"><code>'data'</code></a> event handler is added, or when the
|
||
<a href="#stream_readable_resume"><code>stream.resume()</code></a> method is called. The effect is that, even
|
||
when not using the new <a href="#stream_readable_read_size"><code>stream.read()</code></a> method and
|
||
<a href="#stream_event_readable"><code>'readable'</code></a> event, it is no longer necessary to worry about losing
|
||
<a href="#stream_event_data"><code>'data'</code></a> chunks.</p>
|
||
<p>While most applications will continue to function normally, this introduces an
|
||
edge case in the following conditions:</p>
|
||
<ul>
|
||
<li>No <a href="#stream_event_data"><code>'data'</code></a> event listener is added.</li>
|
||
<li>The <a href="#stream_readable_resume"><code>stream.resume()</code></a> method is never called.</li>
|
||
<li>The stream is not piped to any writable destination.</li>
|
||
</ul>
|
||
<p>For example, consider the following code:</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// WARNING! BROKEN!</span>
|
||
net.createServer(<span class="hljs-function">(<span class="hljs-params">socket</span>) =></span> {
|
||
|
||
<span class="hljs-comment">// We add an 'end' listener, but never consume the data.</span>
|
||
socket.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
<span class="hljs-comment">// It will never get here.</span>
|
||
socket.end(<span class="hljs-string">'The message was received but was not processed.\n'</span>);
|
||
});
|
||
|
||
}).listen(<span class="hljs-number">1337</span>);</code></pre>
|
||
<p>Prior to Node.js 0.10, the incoming message data would be simply discarded.
|
||
However, in Node.js 0.10 and beyond, the socket remains paused forever.</p>
|
||
<p>The workaround in this situation is to call the
|
||
<a href="#stream_readable_resume"><code>stream.resume()</code></a> method to begin the flow of data:</p>
|
||
<pre><code class="language-js"><span class="hljs-comment">// Workaround.</span>
|
||
net.createServer(<span class="hljs-function">(<span class="hljs-params">socket</span>) =></span> {
|
||
socket.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =></span> {
|
||
socket.end(<span class="hljs-string">'The message was received but was not processed.\n'</span>);
|
||
});
|
||
|
||
<span class="hljs-comment">// Start the flow of data, discarding it.</span>
|
||
socket.resume();
|
||
}).listen(<span class="hljs-number">1337</span>);</code></pre>
|
||
<p>In addition to new <code>Readable</code> streams switching into flowing mode,
|
||
pre-0.10 style streams can be wrapped in a <code>Readable</code> class using the
|
||
<a href="#stream_readable_wrap_stream"><code>readable.wrap()</code></a> method.</p>
|
||
<h3><code>readable.read(0)</code><span><a class="mark" href="#stream_readable_read_0" id="stream_readable_read_0">#</a></span></h3>
|
||
<p>There are some cases where it is necessary to trigger a refresh of the
|
||
underlying readable stream mechanisms, without actually consuming any
|
||
data. In such cases, it is possible to call <code>readable.read(0)</code>, which will
|
||
always return <code>null</code>.</p>
|
||
<p>If the internal read buffer is below the <code>highWaterMark</code>, and the
|
||
stream is not currently reading, then calling <code>stream.read(0)</code> will trigger
|
||
a low-level <a href="#stream_readable_read_size_1"><code>stream._read()</code></a> call.</p>
|
||
<p>While most applications will almost never need to do this, there are
|
||
situations within Node.js where this is done, particularly in the
|
||
<code>Readable</code> stream class internals.</p>
|
||
<h3><code>readable.push('')</code><span><a class="mark" href="#stream_readable_push" id="stream_readable_push">#</a></span></h3>
|
||
<p>Use of <code>readable.push('')</code> is not recommended.</p>
|
||
<p>Pushing a zero-byte string, <code>Buffer</code> or <code>Uint8Array</code> to a stream that is not in
|
||
object mode has an interesting side effect. Because it <em>is</em> a call to
|
||
<a href="#stream_readable_push_chunk_encoding"><code>readable.push()</code></a>, the call will end the reading process.
|
||
However, because the argument is an empty string, no data is added to the
|
||
readable buffer so there is nothing for a user to consume.</p>
|
||
<h3><code>highWaterMark</code> discrepancy after calling <code>readable.setEncoding()</code><span><a class="mark" href="#stream_highwatermark_discrepancy_after_calling_readable_setencoding" id="stream_highwatermark_discrepancy_after_calling_readable_setencoding">#</a></span></h3>
|
||
<p>The use of <code>readable.setEncoding()</code> will change the behavior of how the
|
||
<code>highWaterMark</code> operates in non-object mode.</p>
|
||
<p>Typically, the size of the current buffer is measured against the
|
||
<code>highWaterMark</code> in <em>bytes</em>. However, after <code>setEncoding()</code> is called, the
|
||
comparison function will begin to measure the buffer's size in <em>characters</em>.</p>
|
||
<p>This is not a problem in common cases with <code>latin1</code> or <code>ascii</code>. But it is
|
||
advised to be mindful about this behavior when working with strings that could
|
||
contain multi-byte characters.</p>
|
||
<!-- API END -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|