Maison  >  Article  >  interface Web  >  Parlons du module principal de Nodejs : le module stream (voir comment l'utiliser)

Parlons du module principal de Nodejs : le module stream (voir comment l'utiliser)

青灯夜游
青灯夜游avant
2021-12-20 11:13:082201parcourir

Cet article vous donnera une compréhension détaillée du module stream dans Nodejs et présentera le concept et l'utilisation des streams. J'espère qu'il sera utile à tout le monde ! Le module

Parlons du module principal de Nodejs : le module stream (voir comment l'utiliser)

stream est un module très central de Node D'autres modules tels que fs, http, etc. sont basés sur des instances du module stream.

Pour la plupart des novices du front-end, lorsqu'ils débutent avec Node, ils n'ont toujours pas une compréhension claire du concept et de l'utilisation des flux, car il semble y avoir très peu d'applications liées au traitement des « flux » devant -fin du travail.

1. Le flux, c'est quoi ?

Avec le simple mot « débit », on peut facilement avoir les notions de débit d'eau, de débit, etc.

Définition officielle : Stream est une interface abstraite utilisée pour traiter les données de flux dans Node.js

De la définition officielle, on peut voir :

  • Stream est une méthode de traitement de données fournie par Node Tool
  • Stream est un interface abstraite dans Node

Compris avec précision, le flux peut être compris comme un flux de données, qui est un moyen de transmettre des données dans une application. Le flux est un flux de données ordonné avec un point de départ et un point final. 数据流,它是一种用来传输数据的手段,在一个应用程序中,流,是一种有序的,有起点和终点的数据流。

造成我们对stream流不太好的理解的主要原因就是,它是一种抽象的概念。

2. 流,的具体使用场景

为了让我们能够清楚的理解stream模块,我们首先来以具体的应用场景来说明stream模块有哪些实际应用之处。

stream流,在Node中主要应用在大量数据处理的需求上,如fs对大文件的读取和写入、http请求响应、文件的压缩、数据的加密/解密等应用。

Parlons du module principal de Nodejs : le module stream (voir comment lutiliser)

我们以上面的图片说明流的使用,水桶可以理解为数据源,水池可以理解为数据目标,中间连接的管道,我们可以理解为数据流,通过数据流管道,数据从数据源流向数据目标。

3. 流的分类

在Node中,流被分为4类:可读流,可写流,双工流,转换流。

  • Writable: 可以写入数据的流
  • Readable: 可以从中读取数据的流
  • DuplexReadable 和 Writable 的流
  • Transform: 可以在写入和读取数据时修改或转换数据的 Duplex 流

所有的流都是 EventEmitter 的实例。即我们可以通过事件机制监听数据流的变化。

4. 数据模式和缓存区

在深入学习4类流的具体使用之前,我们需要理解两个概念数据模式缓存区,有助于我们在接下来流的学习中更好的理解。

4.1 数据模式

Node.js API 创建的所有流都只对字符串和 Buffer(或 Uint8Array)对象进行操作。

4.2 缓存区

Writable和 Readable

La principale raison pour laquelle nous ne comprenons pas bien le stream est qu'il s'agit d'un concept abstrait. 🎜🎜2. Scénarios d'utilisation spécifiques des flux🎜🎜Afin de bien comprendre le module stream, nous expliquons d'abord les applications pratiques du module stream avec des scénarios d'application spécifiques. 🎜🎜stream, dans Node, est principalement utilisé pour les besoins de traitement de grandes quantités de données, tels que la lecture et l'écriture fs de fichiers volumineux, la réponse à une requête http, la compression de fichiers, le cryptage/déchiffrement de données et d'autres applications. . 🎜🎜Parlons du module principal de Nodejs : le module stream (voir comment lutiliser)🎜🎜nous L'image ci-dessus illustre l'utilisation des flux. Le bucket peut être compris comme une source de données, le pool peut être compris comme une cible de données et le tuyau se connectant au milieu peut être compris comme flux de données, via un pipeline de flux de données, les données circulent de la source de données vers la cible de données. 🎜🎜3. Classification des flux🎜🎜Dans Node, les flux sont divisés en 4 catégories : flux lisible, flux inscriptible, flux duplex et flux de conversion. 🎜🎜🎜Writable🎜 : Un flux qui peut écrire des données🎜🎜Readable🎜 : un flux à partir duquel les données peuvent être lues🎜🎜Duplex🎜 : Lisible et Écrit code > Stream🎜🎜<a href="https://link.juejin.cn?target=http%3A%2F%2Fnodejs.cn%2Fapi%2Fstream.html%23class-streamtransform" target="_blank" rel=" nofollow noopener noreferrer" title="http://nodejs.cn/api/stream.html#class-streamtransform" ref="nofollow noopener noreferrer"><code>Transformer🎜 : peut être écrit et lu Duplex qui modifient ou transforment les données 🎜🎜🎜Tous les flux sont EventEmitter 🎜 exemple. Autrement dit, nous pouvons surveiller les changements dans le flux de données via le mécanisme d'événements. 🎜🎜4. Mode données et zone tampon🎜🎜Avant d'apprendre l'utilisation spécifique des 4 types de flux, nous devons comprendre deux concepts : le mode données et la zone tampon, ce qui est utile. Cela nous aidera à mieux comprendre dans le prochain flux d'étude. 🎜🎜4.1 Mode Données🎜🎜Tous les flux créés par l'API Node.js fonctionnent uniquement avec des chaînes Fonctionner avec des objets Buffer (ou Uint8Array). 🎜🎜4.2 Cache🎜🎜Les flux Writable et Readable sont tous deux Stockez les données dans un tampon interne. 🎜

La quantité de données pouvant être mises en mémoire tampon dépend de l'option highWaterMark transmise au constructeur de flux. Pour les flux ordinaires, l'option highWaterMark spécifie le nombre total d'octets. ;Pour les flux fonctionnant en mode objet, l'option highWaterMark spécifie le nombre total d'objets. L'option highWaterMark 选项, 对于普通的流,highWaterMark 选项指定字节的总数;对于在对象模式下操作的流,highWaterMark选项指定对象的总数。

highWaterMark 选项是阈值,而不是限制:它规定了流在停止请求更多数据之前缓冲的数据量。

当实现调用 stream.push(chunk) 时,数据缓存在 Readable 流中。 如果流的消费者没有调用 stream.read(),则数据会一直驻留在内部队列中,直到被消费。

一旦内部读取缓冲区的总大小达到 highWaterMark 指定的阈值,则流将暂时停止从底层资源读取数据,直到可以消费当前缓冲的数据

当重复调用 writable.write(chunk) 方法时,数据会缓存在 Writable 流中。

5. 可读流

5.1 流读取的流动与暂停

Readable

highWaterMark est un seuil, pas une limite : elle dicte la quantité de données que le flux met en mémoire tampon avant de cesser de demander plus de données.
  • Lorsque l'implémentation appelle stream.push(chunk)

    Lorsqu'il est mis en cache dans le flux Readable. Si le consommateur du flux n'appelle pas stream.read()

    , les données seront toujours être résident Rester dans la file d'attente interne jusqu'à ce qu'il soit consommé.
  • Une fois que la taille totale du tampon de lecture interne atteint le seuil spécifié par highWaterMark, le flux cessera temporairement de lire les données de la ressource sous-jacente jusqu'à ce que les données actuellement mises en mémoire tampon puissent être consommées

    Lorsqu'il est appelé à plusieurs reprises writable.write(chunk)
  • méthode, les données seront être mis en cache dans le flux Writable.
  • 5. Flux lisibles

    • 5.1 Flux et pause pour la lecture du flux
    • Lisible Les flux s'exécutent efficacement dans l'un des deux modes suivants : flux et pause.
  • Mode flux : lisez les données de la couche inférieure du système et poussez-les () vers la zone de cache. Après avoir atteint le highWaterMark, push() renverra false et les ressources cesseront de circuler vers la zone de cache, et l'événement de données sera déclenché pour consommer les données.

    • Mode Pause : tous les flux lisibles démarrent en mode pause Paused et la méthode stream.read() doit être explicitement appelée pour lire les données du flux. Chaque fois que les données atteignent la zone tampon, un événement lisible sera déclenché, c'est-à-dire que chaque push() déclenchera un événement lisible.
  • Comment passer du mode pause au mode fluide :

Ajouter un handle d'événement de données Appeler la méthode stream.resume()

Appeler la méthode stream.pipe() pour envoyer des données à Writable

Mode fluide Façons de passer en mode pause :

S'il n'y a pas de cible de pipeline, en appelant la méthode stream.pause().

Supprimez toutes les cibles du pipeline s'il y en a. Plusieurs cibles de pipeline peuvent être supprimées en appelant la méthode stream.unpipe().

5.2 Exemples courants de flux lisibles

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. Les flux inscriptibles

🎜🎜🎜6.1 Le flux et la suspension des flux inscriptibles🎜🎜🎜🎜les flux inscriptibles sont similaires aux flux lisibles, les données Quand elles circulent terminé, il sera écrit directement dans la zone de cache. Lorsque la vitesse d'écriture est lente ou que l'écriture est suspendue, le flux de données sera mis en cache dans la zone de cache 🎜🎜Lorsque le producteur écrit trop vite, le pool de files d'attente sera rempli ; Après cela, une « contre-pression » apparaîtra. À ce moment, vous devez dire au producteur de suspendre la production. Lorsque la file d'attente est libérée, le flux inscriptible enverra un message de vidange au producteur pour reprendre la production. 🎜🎜🎜🎜6.2 Exemple de flux inscriptible🎜🎜🎜
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;)
})
🎜Pour plus de connaissances sur les nœuds, veuillez visiter : 🎜Tutoriel Nodejs🎜 ! ! 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer