stream nodejs,node stream
本文带你详细了解Nodejs中的stream模块,并介绍stream的概念和用法,希望对你有所帮助!
node.js速度课程简介:进入学习
流模块是Node中非常核心的模块,其他模块如fs、http都是基于流模块的实例。
但是大部分前端小白同学在new Node的学习过程中,对于flow的概念和使用仍然没有一个清晰的认识,因为在前端工作中似乎很少有涉及到 flow 处理的应用。
1. 流,是什么?
单纯的“流”这个词,我们很容易产生水流、流量等概念。
从官方的定义中,我们可以看出:
Stream是处理Node提供的数据的工具流。它是Node中的一个抽象接口。可以准确理解为数据流。它是一种传输数据的手段。在应用程序中,流是有起点和终点的有序数据流。
我们对stream理解不好的主要原因是它是一个抽象的概念。
2. 流,的具体使用场景
为了让我们更清楚的了解stream模块,我们先用具体的应用场景来说明stream模块的实际应用。
Stream,在Node中,主要用于大量的数据处理需求,如fs读写大文件、http请求响应、文件压缩、数据加密/解密等应用。
我们用上图来说明心流的使用。桶可以理解为数据源,池可以理解为数据目标,中间连接的管道可以理解为数据流。通过数据流管道,数据从数据源流向数据目标。
3. 流的分类
在Node中,流分为四类:可读流、可写流、双工流和转换流。
Writeable:可以写入数据的流。可读:可以从中读取数据的流。双工:可读和可写流。转换:在读写数据时可以修改或转换数据的双工流。所有流都是EventEmitter的实例。也就是我们可以通过事件机制来监控数据流的变化。
4. 数据模式和缓存区
在深入研究四类流的具体使用之前,我们需要了解两个概念性的数据模式和缓冲区,这将有助于我们在接下来的流学习中有更好的理解。
4.1 数据模式
Node.js API创建的所有流只对字符串和缓冲区(或Uint8Array)对象进行操作。
4.2 缓存区
可写和可读流都将数据存储在内部缓冲区中。
可以缓冲的数据量取决于传递给流的构造函数的highWaterMark选项。对于普通流,highWaterMark选项指定总字节数;对于在对象模式下运行的流,highWaterMark选项指定对象的总数。
highWaterMark选项是一个阈值,而不是一个限制:它指定流在停止请求更多数据之前缓冲的数据量。
当实现调用stream.push(chunk)时,数据缓存在可读流中。如果流的使用者不调用stream.read(),则数据将留在内部队列中,直到被使用。
一旦内部读取缓冲区的总大小达到highWaterMark指定的阈值,流将暂时停止从基础资源读取数据,直到它可以使用当前缓冲的数据。
当重复调用writable.write(chunk)方法时,数据被缓存在可写流中。
5. 可读流
5.1 流读取的流动与暂停
可读流以两种模式之一有效运行:流和暂停。
流模式:从系统底层读取数据,并将()推送到缓冲区。当达到highWaterMark时,push()将返回false,资源将停止流向缓冲区,从而触发数据事件来消耗数据。
暂停模式:所有可读流都以暂停模式启动,并且必须显式调用stream.read()方法来从流中读取数据。每次数据到达缓冲区时,都会触发一个可读事件,即每次push()都会触发可读。
如何从暂停模式切换到流动模式:
添加数据事件句柄,调用stream.resume()方法,调用stream.pipe()方法,将数据发送到Writable。如何将流动模式切换到暂停模式:
如果没有管道目标,则调用stream.pause()方法。如果有管道目标,请删除所有管道目标。通过调用stream.unpipe()方法,可以删除多个管道目标。5.2 可读流常用示例
从“path”导入路径;
从“fs”导入fs,{ read };
const file path=path . join(path . resolve(), files , text . txt );
const readable=fs . createreadstream(file path);
//如果使用readable.setEncoding()方法为流指定了默认编码,侦听器回调将数据块作为字符串传入;否则,数据将作为缓冲区传入。
readable . set encoding( utf8 );
设str=“”;
readable.on(open ,(fd)={
Console.log(开始读取文件)
})
//只要流将数据块的所有权交给使用者,就会触发“data”事件。
readable.on(data ,(data)={
str=数据;
Console.log(读取数据)
})
//该方法将导致流模式中的流停止触发“数据”事件,并切换到暂停模式。任何可用的数据都将保存在内部缓冲区中。
readable . pause();
//方法使显式暂停的可读流恢复,并触发“data”事件将流切换到流模式。
readable . resume();
//当调用stream.pause()且readableFlowing不为false时,将触发“pause”事件。
readable.on(pause ,()={
Console.log(读取暂停)
})
//当调用stream.resume()且readableFlowing不为true时,会触发“resume”事件。
readable.on(resume ,()={
Console.log(重新流动)
})
//当流中不再有数据可供使用时,将触发“end”事件。
readable.on(end ,()={
Console.log(“文件读取完成”);
})
//当流及其任何基础资源(如文件描述符)都已关闭时,将触发“close”事件。
readable.on(close ,()={
Console.log(“关闭文件读取”)
})
//将destWritable流绑定到readable,这样可以自动切换到flow模式,将其所有数据推送到绑定的Writable。数据流将被自动管理。
可读管道(可写)
//如果基础流由于基础内部故障而无法生成数据,或者当流实现试图推送无效数据块时,可能会发生这种情况。
readable.on(error ,(err)={
console.log(错误)
Console.log(“文件读取错误”)
})
6. 可写流
6.1 可写流的流动与暂停
可写流类似于可读流。当数据流到来时,它将被直接写入缓冲区。当写入速度较慢或写入暂停时,数据流将缓存在缓冲区中。
当生产者写得太快,填满了队列池,就会产生“反压”。这时候就要告诉生产商暂停生产了。当队列被释放时,可写流将向生产者发送排出消息,让其恢复生产。
6.2 可写流示例
从“path”导入路径;
从“fs”导入fs,{ read };
const file path=path . join(path . resolve(), files , text . txt );
const copy file=path . join(path . resolve(), files , copy . txt );
设str=“”;
//创建可读的流
const readable=fs . createreadstream(file path);
//如果使用readable.setEncoding()方法为流指定了默认编码
readable . set encoding( utf8 );
//创建可写的流
const wirte able=fs . createwritestream(copy file);
//编码
wirte table . setdefaultencoding( utf8 );
readable.on(open ,(fd)={
Console.log(开始读取文件)
})
//只要流将数据块的所有权交给使用者,就会触发“data”事件。
readable.on(data ,(data)={
str=数据;
Console.log(读取数据);
//写
wirte table . write(data, utf8 );
})
wirte table . on( open ,()={
Console.log(开始写入数据)
})
//如果对stream.write(chunk)的调用返回false,则在适合继续向流中写入数据时,将触发“drain”事件。
//即生产数据的速度快于写入速度。缓冲区填满后,将暂停生产以从底层读取数据。
//释放可写缓冲区后,将发送一个drain事件,让生成器继续读取。
wirte table . on( drain ,()={
Console.log(继续写)
})
//在调用stream.end()方法并且所有数据都刷新到底层系统后,会触发“finish”事件。
wirte table . on( finish ,()={
Console.log(“数据写入完成”)
})
readable.on(end ,()={
//在读取数据时通知可写流。
wirteable.end()
})
//当在可读流上调用stream.pipe()方法以将此可写流添加到其目标集时,将触发“pipe”事件。
//readable.pipe(destWriteable)
wirteable.on(管道,()={
Console.log(“管道流创建”)
})
wirte table . on( error ,()={
Console.log(数据写入错误)
})更多关于node的信息,请访问:nodejs教程!那就是说Nodejs: stream模块中核心模块的细节了(看怎么用)。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。