Stream可以是可读的,也可以是可写的,也可以是可读可写的。所有流都是EventEmitter的实例。对象模式所有使用Node.jsAPI创建的流对象只能对字符串和Buffer(或Unit8Array)进行操作。但是一些第三方流实现能够操作其他类型的javascript值(null除外,它在流处理中有特殊含义),这种类型的流被认为工作在“对象模式”。Writable和Readable流都将数据存储在内部缓冲区中,当可读流的实现调用stream.push(chunk)时,将数据放入缓冲区中。如果流的消费者没有调用stream.read()方法,它会一直存在于内部队列中,直到被消费。缓存的大小取决于传递给流构造函数的highWaterMark选项。当内部可读缓存的大小达到highWaterMark指定的阈值时,流将暂停从底层资源读取数据,直到当前缓存的数据被消费。可写流通过重复调用writable.write(chunk)方法将数据放入缓存。当内部可写缓存的总大小小于highWaterMark指定的阈值时,调用writable.write()返回true。一旦达到或超过highWaterMark,调用writable.write()返回false。这时,应该停止向流中写入数据。,直到引流事件被触发。可读流可读如fs.createReadStream()可读流(Readablestreams)是对提供数据的源(source)的抽象。流式(flowmode)和暂停(pausemode)两种工作模式flowing模式:availablereadstream自动从系统底层读取数据,并通过事件的事件尽快将数据提供给应用程序事件发射器()接口。在暂停模式下:必须显式调用stream.read()方法才能从流中读取数据片段。初始工作模式为pausedReadablestream,可以通过三种方式切换到flowing模式。监听data事件调用stream.resume()方法调用stream.pipe()方法发送数据给Writable可读流可以通过两种方式切换到paused如果可读流没有桥接,可写流变成一个pipeline,调用stream.pause()实现,如果可读流桥接多个可写流形成管道,关闭事件通过取消数据事件监听,调用stream.unpipe()方法移除所有管道目标实现:在流或其基础资源(例如文件)上关闭后触发。一旦事件触发,流将不会再触发任何事件。数据事件:当流将数据传递给消费者时触发。当流转换为流动模式时会触发此事件。处理器的参数是一个Buffer对象。如果调用Readable的setEncoding(encoding)方法,处理器的参数是一个String对象。结束事件:当流中没有更多数据可供使用时触发。constreadable=readableStreamSomehow()readable.on('data',(chunk)=>{console.log(`收到缓冲区数据的${chunk.length}字节。`)})readable.on('end',()=>{console.log('nomoredata.')})error事件:通常底层系统中的内部错误会阻止生成数据,或者在流实现试图传递不正确的数据时发生。回调函数将接收一个错误对象。可读事件:当流中的数据可供读取时将被触发。stream.read()返回可用数据。constreadable=readableStreamSomehow()readable.on('readable',()=>{//Thereissomedatatoread})当流数据到达末尾时也会触发该事件。触发顺序在结束事件之前。stream.read()返回null//foo.txt是一个空文件constfs=require('fs')constrr=fs.createReadStream('foo.txt')rr.on('readable',()=>{console.log('readable',rr.read)//null})rr.on('end',()=>{console.log('end')//end})readable.pipe(destination[,options]):将一个可写对象绑定到一个可读对象上,形成一个管道,并将所有数据传递给绑定的可写对象。可以在单个可读流上绑定多个可写流。constr=fs.createReadStream('file.txt')constz=zlib.createGzip()constw=fs.createWriteStream('file.txt.gz')r.pipe(z).pipe(w)默认情况下,当源可读流触发结束事件时,目标流也会调用stream.end()方法结束写入。要禁用此默认行为,应将结束选项指定为false。reader.pipe(writer,{end:false})reader.on('end',()=>{writer.end('goodbye)})如果在处理可读流时发生错误,目标可写流将不会自动关闭。如果发生错误,则需要手动关闭所有流以避免内存泄漏。通常,建议开发人员避免使用'readable'事件和readable.read()方法,而应改用readable.pipe()或'data'事件。writable.unpipe([destination]):readable.unpipe()方法将之前由stream.pipe()方法绑定的流分开。如果没有传入destination,所有绑定的流都会被分离。如果传入了destination,但是还没有被pipe()绑定,那么这个方法就不起作用了。可写流可写流如fs.createWriteStream()可写流是目的地的抽象,它允许将数据写入关闭事件:在流中或底层资源(如文件)关闭后触发,流将事件触发后不触发任何事件。drainevent`:如果调用stream.write(chunk)方法返回false,stream会在合适的时候触发drain事件,才能继续向stream写入数据。errorevent`:当写入数据或使用管道(pipe)出错时触发。当一个事件发生时,回调函数只会接收一个Error参数。注意:当错误事件发生时,流并没有关闭。finish事件:stream.end()方法被调用,buffer数据传递给底层系统后,会触发finish事件。pipe事件:当可读流调用stream.pipe()方法,当前可写流被添加到目标流时,会在可写流上触发pipe事件。constwriter=writeStreamSomehow()constreader=readStreamSomehow()writer.on('pipe',(src)=>{console.log('pipingintothewriter')assert.equal(src,reader)})reader.pipe(writer)writable.end([chunk][,encoding][,callback]):调用writable.end()方法表示接下来没有数据写入writable。通过传入可选的chunk和encoding参数,您可以在关闭流之前写入另一段数据。如果传入一个可选的回调函数,它将作为完成事件的回调函数。在调用stream.end()之后调用stream.write()将导致错误。//写hello,结束写worldconstfile=fs.createWriteStream('example.txt)file.write('hello,')file.end('wrold!)//后面不允许写数据。write(chunk[,encoding][,callback]):向流中写入数据,数据处理完成后调用callback。我们建议一旦write()返回false,在'drain'事件触发之前不能写入任何数据块。writable.uncork()可以读写Duplex流如net.Socket()Duplex流可以在读写过程中修改和转换数据Transform如zlib.createDeflate()
