ホームページ  >  記事  >  ウェブフロントエンド  >  Nodejs のコア モジュールであるストリーム モジュールについて話しましょう (使い方を参照)

Nodejs のコア モジュールであるストリーム モジュールについて話しましょう (使い方を参照)

青灯夜游
青灯夜游転載
2021-12-20 11:13:082291ブラウズ

この記事では、Nodejs のストリーム モジュールについて詳しく理解し、ストリームの概念と使い方を紹介します。

Nodejs のコア モジュールであるストリーム モジュールについて話しましょう (使い方を参照)

stream モジュールは、Node の非常にコアなモジュールです。fs、http などの他のモジュールはすべて、stream モジュールのインスタンスに基づいています。 。

ほとんどのフロントエンド初心者にとって、Node を初めて使い始めるときは、ストリームの概念と使用法をまだ明確に理解していません。なぜなら、「ストリーム」についてはほとんど理解されていないからです。フロントエンド作業関連アプリケーションを処理します。

1. 流れ、それは何ですか?

「流れ」という単純な単語から、水の流れ、流れなどの概念が簡単に得られます。

公式定義: ストリームは、Node.js でストリーム データを処理するために使用される抽象インターフェイスです。

公式定義から、次のことがわかります。

  • Stream は Node が提供するデータを処理するためのツールです。
  • Stream は Node の抽象インターフェイスです。

ストリームを正確に理解すると、データの流れとして理解できます。 (データ送信手段) アプリケーションでは、ストリームは開始点と終了点を持つ順序付けされたデータ フローです。

ストリームがよく理解できない主な理由は、ストリームが抽象的な概念であるためです。

2. ストリームの具体的な使用シナリオ

ストリーム モジュールを明確に理解するために、まず、具体的なアプリケーション シナリオを使用してストリーム モジュールの実際のアプリケーションを説明しましょう。 Node 内の

stream ストリームは、主に 大量のデータ の処理要件 (大きなファイルの fs の読み取りと書き込み、http リクエストの応答、ファイル圧縮、データの暗号化/復号化など) で使用されます。およびその他のアプリケーション。

Nodejs のコア モジュールであるストリーム モジュールについて話しましょう (使い方を参照)

上の図を使用してストリームの使用法を説明します。バケットは データ ソース、プールは # として理解できます。 ##data target 、中間接続パイプライン。 データ フロー データ フロー パイプライン を通じて、データ ソースからデータ ターゲットへのデータ フローとして理解できます。

3. ストリームの分類

Node では、ストリームは読み取り可能ストリーム、書き込み可能ストリーム、二重化ストリーム、変換ストリームの 4 つのカテゴリに分類されます。

のインスタンスです

。つまり、イベント メカニズムを通じてデータ フローの変化を監視できます。 4. データ モードとキャッシュ領域4 種類のストリームの具体的な使用方法を学ぶ前に、2 つの概念

データ モード

キャッシュ領域を理解する必要があります。

これは、次の学習フローでの理解を深めるのに役立ちます。 4.1 データ モード

Node.js API によって作成されたすべてのストリームは、strings および

専用です。操作対象の Buffer

(または Uint8Array) オブジェクト。 4.2 バッファ

Writable ストリームと

Readable

ストリームはどちらも、データを内部バッファに保存します。バッファ。 <p>バッファリングできるデータの量は、ストリームのコンストラクターに渡される <code>highWaterMark オプションによって異なります。通常のストリームの場合、highWaterMark オプションは バイトの合計数を指定します ;オブジェクト モードで動作するストリームの場合、highWaterMark オプションはオブジェクトの総数を指定します。

highWaterMark オプションは、制限ではなくしきい値です。ストリームが追加のデータの要求を停止する前にバッファリングするデータ量を決定します。

実装が stream.push(chunk) を呼び出すと、データは Readable ストリームにキャッシュされます。ストリームのコンシューマーが stream.read() を呼び出さない場合、データは消費されるまで内部キューに残ります。

内部読み取りバッファーの合計サイズが highWaterMark で指定されたしきい値に達すると、現在バッファリングされているデータが消費されるまで、ストリームは基礎となるリソースからのデータの読み取りを一時的に停止します。

writable.write(chunk) メソッドが繰り返し呼び出される場合、データは Writable ストリームにキャッシュされます。

5. 読み取り可能なストリーム

##5.1 ストリーム読み取りの流れと一時停止

Readable

ストリームは効果的に実行されます。フローモードと一時停止モードの 2 つのモードのいずれかです。

    フロー モード: システムの最下層からデータを読み取り、push() でキャッシュ領域に移動します。highWaterMark に到達すると、push() は false を返し、リソースのフローが停止します。データがキャッシュ領域に追加され、データ イベントの消費がトリガーされます。
  • 一時停止モード: すべての Readable ストリームは一時停止モードで開始され、ストリームからデータを読み取るには stream.read() メソッドを明示的に呼び出す必要があります。データがバッファ領域に到達するたびに、読み取り可能イベントがトリガーされます。つまり、すべての Push() が読み取り可能をトリガーします。
  • 一時停止モードからフロー モードに切り替える方法:
  • データ イベント ハンドルを追加します
    • stream.resume() メソッドを呼び出します
    • stream.pipe() メソッドを呼び出してデータを Writable に送信します
  • フロー モードを一時停止モードに切り替える方法:
  • パイプライン ターゲットでない場合は、stream.pause() メソッドを呼び出します。
    • パイプライン ターゲットがある場合は、すべてのパイプライン ターゲットを削除します。 stream.unpipe() メソッドを呼び出すことで、複数のパイプライン ターゲットを削除できます。
#5.2 読み取り可能なストリームの一般的な例

import path from &#39;path&#39;;
import fs, { read } from &#39;fs&#39;;

const filePath = path.join(path.resolve(), &#39;files&#39;, &#39;text.txt&#39;);

const readable = fs.createReadStream(filePath);
// 如果使用 readable.setEncoding() 方法为流指定了默认编码,则监听器回调将把数据块作为字符串传入;否则数据将作为 Buffer 传入。
readable.setEncoding(&#39;utf8&#39;);
let str = &#39;&#39;;

readable.on(&#39;open&#39;, (fd) => {
  console.log(&#39;开始读取文件&#39;)
})
// 每当流将数据块的所有权移交给消费者时,则会触发 &#39;data&#39; 事件
readable.on(&#39;data&#39;, (data) => {
  str += data;
  console.log(&#39;读取到数据&#39;)
})
// 方法将导致处于流动模式的流停止触发 &#39;data&#39; 事件,切换到暂停模式。 任何可用的数据都将保留在内部缓冲区中。
readable.pause();
// 方法使被显式暂停的 Readable 流恢复触发 &#39;data&#39; 事件,将流切换到流动模式。
readable.resume();
// 当调用 stream.pause() 并且 readableFlowing 不是 false 时,则会触发 &#39;pause&#39; 事件。
readable.on(&#39;pause&#39;, () => {
  console.log(&#39;读取暂停&#39;)
})
// 当调用 stream.resume() 并且 readableFlowing 不是 true 时,则会触发 &#39;resume&#39; 事件。
readable.on(&#39;resume&#39;, () => {
  console.log(&#39;重新流动&#39;)
})
// 当流中没有更多数据可供消费时,则会触发 &#39;end&#39; 事件。
readable.on(&#39;end&#39;, () => {
  console.log(&#39;文件读取完毕&#39;);
})
// 当流及其任何底层资源(例如文件描述符)已关闭时,则会触发 &#39;close&#39; 事件。
readable.on(&#39;close&#39;, () => {
  console.log(&#39;关闭文件读取&#39;)
})
// 将 destWritable 流绑定到 readable,使其自动切换到流动模式并将其所有数据推送到绑定的 Writable。 数据流将被自动管理
readable.pipe(destWriteable)
// 如果底层流由于底层内部故障而无法生成数据,或者当流实现尝试推送无效数据块时,可能会发生这种情况。
readable.on(&#39;error&#39;, (err) => {
  console.log(err)
  console.log(&#39;文件读取发生错误&#39;)
})
6. 書き込み可能なストリーム

6.1 書き込み可能ストリームのフローと一時停止

書き込み可能ストリームは読み取り可能ストリームと似ており、データがオーバーフローすると、バッファに直接書き込まれます。エリア。書き込み速度が遅い場合、または書き込みが一時停止されている場合、データ ストリームはキャッシュ領域にキャッシュされます。プレッシャー」、この時点で、プロデューサーに生産を一時停止するように指示する必要があります。キューが解放されると、書き込み可能ストリームは、生産を再開するためにプロデューサーにドレイン メッセージを送信します。

6.2 書き込み可能なストリームの例

import path from &#39;path&#39;;
import fs, { read } from &#39;fs&#39;;

const filePath = path.join(path.resolve(), &#39;files&#39;, &#39;text.txt&#39;);
const copyFile = path.join(path.resolve(), &#39;files&#39;, &#39;copy.txt&#39;);

let str = &#39;&#39;;
// 创建可读流
const readable = fs.createReadStream(filePath);
// 如果使用 readable.setEncoding() 方法为流指定了默认编码
readable.setEncoding(&#39;utf8&#39;);

// 创建可写流
const wirteable = fs.createWriteStream(copyFile);
// 编码
wirteable.setDefaultEncoding(&#39;utf8&#39;);

readable.on(&#39;open&#39;, (fd) => {
  console.log(&#39;开始读取文件&#39;)
})
// 每当流将数据块的所有权移交给消费者时,则会触发 &#39;data&#39; 事件
readable.on(&#39;data&#39;, (data) => {
  str += data;
  console.log(&#39;读取到数据&#39;);

  // 写入
  wirteable.write(data, &#39;utf8&#39;);
})

wirteable.on(&#39;open&#39;, () => {
  console.log(&#39;开始写入数据&#39;)
})
// 如果对 stream.write(chunk) 的调用返回 false,则 &#39;drain&#39; 事件将在适合继续将数据写入流时触发。
// 即生产数据的速度大于写入速度,缓存区装满之后,会暂停生产着从底层读取数据
// writeable缓存区释放之后,会发送一个drain事件让生产者继续读取
wirteable.on(&#39;drain&#39;, () => {
  console.log(&#39;继续写入&#39;)
})
// 在调用 stream.end() 方法之后,并且所有数据都已刷新到底层系统,则触发 &#39;finish&#39; 事件。
wirteable.on(&#39;finish&#39;, () => {
  console.log(&#39;数据写入完毕&#39;)
})

readable.on(&#39;end&#39;, () => {
  // 数据读取完毕通知可写流
  wirteable.end()
})
// 当在可读流上调用 stream.pipe() 方法将此可写流添加到其目标集时,则触发 &#39;pipe&#39; 事件。
// readable.pipe(destWriteable)
wirteable.on(&#39;pipe&#39;, () => {
  console.log(&#39;管道流创建&#39;)
})

wirteable.on(&#39;error&#39;, () => {
  console.log(&#39;数据写入发生错误&#39;)
})
ノード関連の詳細については、nodejs チュートリアルを参照してください。 !

以上がNodejs のコア モジュールであるストリーム モジュールについて話しましょう (使い方を参照)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。