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
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.
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 :
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流不太好的理解的主要原因就是,它是一种抽象的概念。
为了让我们能够清楚的理解stream模块,我们首先来以具体的应用场景来说明stream模块有哪些实际应用之处。
stream流,在Node中主要应用在大量数据
处理的需求上,如fs对大文件的读取和写入、http请求响应、文件的压缩、数据的加密/解密等应用。
我们以上面的图片说明流的使用,水桶可以理解为数据源
,水池可以理解为数据目标
,中间连接的管道,我们可以理解为数据流
,通过数据流管道
,数据从数据源流向数据目标。
在Node中,流被分为4类:可读流,可写流,双工流,转换流。
Writable
: 可以写入数据的流Readable
: 可以从中读取数据的流Duplex
: Readable
和 Writable
的流Transform
: 可以在写入和读取数据时修改或转换数据的 Duplex
流所有的流都是 EventEmitter
的实例。即我们可以通过事件机制监听数据流的变化。
在深入学习4类流的具体使用之前,我们需要理解两个概念数据模式
和缓存区
,有助于我们在接下来流的学习中更好的理解。
4.1 数据模式
Node.js API 创建的所有流都只对字符串
和 Buffer
(或 Uint8Array
)对象进行操作。
4.2 缓存区
Writable
和 Readable
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. . 🎜🎜🎜🎜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.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. stream.push(chunk)
Lorsqu'il est mis en cache dans le flux Readable
. Si le consommateur du flux n'appelle pas stream.read()
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éesLorsqu'il est appelé à plusieurs reprises writable.write(chunk)
Writable
. 5. Flux lisibles
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.
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 à WritableMode 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
🎜🎜🎜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 'path'; import fs, { read } from 'fs'; const filePath = path.join(path.resolve(), 'files', 'text.txt'); const copyFile = path.join(path.resolve(), 'files', 'copy.txt'); let str = ''; // 创建可读流 const readable = fs.createReadStream(filePath); // 如果使用 readable.setEncoding() 方法为流指定了默认编码 readable.setEncoding('utf8'); // 创建可写流 const wirteable = fs.createWriteStream(copyFile); // 编码 wirteable.setDefaultEncoding('utf8'); readable.on('open', (fd) => { console.log('开始读取文件') }) // 每当流将数据块的所有权移交给消费者时,则会触发 'data' 事件 readable.on('data', (data) => { str += data; console.log('读取到数据'); // 写入 wirteable.write(data, 'utf8'); }) wirteable.on('open', () => { console.log('开始写入数据') }) // 如果对 stream.write(chunk) 的调用返回 false,则 'drain' 事件将在适合继续将数据写入流时触发。 // 即生产数据的速度大于写入速度,缓存区装满之后,会暂停生产着从底层读取数据 // writeable缓存区释放之后,会发送一个drain事件让生产者继续读取 wirteable.on('drain', () => { console.log('继续写入') }) // 在调用 stream.end() 方法之后,并且所有数据都已刷新到底层系统,则触发 'finish' 事件。 wirteable.on('finish', () => { console.log('数据写入完毕') }) readable.on('end', () => { // 数据读取完毕通知可写流 wirteable.end() }) // 当在可读流上调用 stream.pipe() 方法将此可写流添加到其目标集时,则触发 'pipe' 事件。 // readable.pipe(destWriteable) wirteable.on('pipe', () => { console.log('管道流创建') }) wirteable.on('error', () => { console.log('数据写入发生错误') })
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!