当前位置: 首页 > 后端技术 > Node.js

从可读流(readablestream)读取数据的方式

时间:2023-04-03 10:08:41 Node.js

可读流是对数据源的一种抽象。从Readable中读取数据有两种模式,非流动(non-flowingmode也叫paused)模式和流动(flow)模式。非流模式在非流模式下,当流中有可读数据时,会触发可读事件,所以当事件触发时,需要反复调用流的read方法,从中获取最新的数据缓存直到read方法返回null,表示没有数据可读,新建的可读流默认是这种模式。常用方法如下:conststream=fs.createReadStream(path.resolve(__dirname,'./xxx.js'));stream.on('readable',()=>{letchunk;while(null!==(chunk=stream.read())){console.log('chunk:'+chunk.toString());}});在不指定编码方式的前提下,read方法返回Buffer,可以调用setEncoding方法指定数据的编码方式,这样调用read方法时就可以直接获取字符串。提前指定编码的好处是对于多字节的字符流,会保证多个字节不会被拆分成不同的chunk:conststream=fs.createReadStream(path.resolve(__dirname,'./print.js'),{编码:'utf8'});stream.on('readable',()=>{letchunk;while(null!==(chunk=stream.read())){console.log('chunk:'+chunk);}});在非流模式下调用Readable.resume()或通过管道连接到Writable以切换到流模式。如果此时没有注册数据事件处理器,新产生的数据就会丢失。流模式可以通过注册数据事件处理函数,将可读流切换为流模式。在这种模式下,当数据源中准备好新数据时,新数据将传递给数据事件处理函数,可以在函数处理新数据时使用。例如,读取文件内容如下:conststream=fs.createReadStream(path.resolve(__dirname,'./print.js'),{encoding:'utf8'});letchunks='';stream.on('data',(chunk)=>{chunks+=chunk;});stream.on('end',()=>{console.log(chunks);});在streaming模式下,可以通过两种方式切换回pause模式:调用pause方法;当可读流通过pipe管道连接到其他流时,调用unpipe也会将流切换到暂停模式;在流模式下注册可读事件处理器会停止流,需要通过read读取数据;如果去掉可读处理函数,如果有数据处理函数,流会重新进入流动模式;异步迭代器新版本node中Readable实现了一个异步迭代器,可以更方便的读取数据:conststream=fs.createReadStream(path.resolve(__dirname,'./print.js'),{encoding:'utf8'});asyncfunctiongetData(stream){letchunks='';forawait(letchunkofstream){chunks+=chunk;}returnchunks;}getData(stream).then(data=>console.log(data));如果循环通过break、return、throw终止,流将被销毁。每次读取的chunk大小等于流的highWaterMark选项。如果不指定此选项,默认值为64kb,因此如果文件大小小于此值,文件内容将以单个块返回。互补流中的数据也有两种模式,二进制模式和对象模式。二进制方式读取的数据类型为Buffer或String,前面的例子都是以二进制方式读取数据。在对象模式下,可以返回任何javascript对象。这是一个简单的例子。Readable.from()创建的流默认为objectMode:conststream=Readable.from([{name:'Bob',},{name:'Jenny'},{name:'Lili'}]);asyncfunctiongetData(stream){forawait(letchunkofstream){console.log(chunk);}}getData(流);输出如下:{name:'Bob'}{name:'Jenny'}{name:'Lili'}