美文网首页
对nodejs中流的理解

对nodejs中流的理解

作者: 冻桃花 | 来源:发表于2018-02-04 14:05 被阅读0次

    一,为什么需要流?

            当我们学习一个东西的时候,首先我们要知道为什么要学习?那我们为什么要使用流呢?在node中读取文件的方式有来两种,一个是利用fs模块,一个是利用流来读取。如果读取小文件,我们可以使用fs读取,fs读取文件的时候,是将文件一次性读取到本地内存。而如果读取一个大文件,一次性读取会占用大量内存,效率很低,这个时候需要用流来读取。流是将数据分割段,一段一段的读取,效率很高。

    二,流的概念

    流是一种抽象的接口,node中很多对象都对它进行了实现。

    所有流的对象都是EventEmitter的实例,都实现了EventEmitter的接口。

    也就是流具有事件的能力,可以通过发射事件来反馈流的状态。这样我们就可以注册监听流的事件,来达到我们的目的。也就是我们订阅了流的事件,这个事件触发时,流会通知我,然后我就可以做相应的操作了。

    三,流的分类

            Readable Stream :可读数据流

            Writeable Stream :可写数据流

            Duplex Stream :双向数据流,可以同时读和写

            Transform Stream: 转换数据流,可读可写,同时可以转换(处理)数据

    四,可读流介绍

    可读流的两种模式

    可读流有两种模式:flowing和paused

    1)在流动模式下,可读流自动从系统底层读取数据,并通过EventEmitter接口的事件尽快

    将数据提供给应用。

    2)在暂停模式下,必须显示调用stream.read()方法来从流中读取数据片段。

    注意:如果可读流切换到流动模式,并且没有消费者处理流中的数据,这些数据将会丢失。

    下面介绍Readable流有以下几种事件:

         1. 'Readable'事件

         2. 'data'事件 - 数据正在传递时,触发该事件(以chunk数据块为对象)

         3. 'end'事件 - 数据传递完成后,会触发该事件。

         4. 'close'事件

         5. 'error'事件

     所有这些事件都可以在官方API文档中找到例子。我们可以监听流的这些事件,来完成相应操作。

    我们来写个小例子:

    ```

    let fs = require('fs');

    let ReadStream = require('./ReadStream');

    let rs = ReadStream('./1.txt', {

        flags: 'r',

        encoding: 'utf8',

        start: 3,

        end: 7,

        highWaterMark: 3

    });

    rs.on('open', function () {

        console.log("open");

    });

    rs.on('data', function (data) {

        console.log(data);

    });

    rs.on('end', function () {

        console.log("end");

    });

    rs.on('close', function () {

        console.log("close");

    });

    /**

    open

    456

    789

    end

    close

    **/

    ```

    五,可写流介绍

    常用的方法:

    1,Writable流的write(chunk[,encoding] [,callback])方法可以把数据写入流中。

    其中,chunk是待写入的数据,是Buffer或String对象。这个参数是必须的,其它参数都是可选的。如果chunk是String对象,encoding可以用来指定字符串的编码格式,write会根据编码格式将chunk解码成字节流再来写入。callback是数据完全刷新到流中时会执行的回调函数。write方法返回布尔值,当数据被完全处理后返回true(不一定是完全写入设备哦)。

    2,Writable流的end([chunk] [,encoding] [,callback])方法可以用来结束一个可写流。它的三个参数都是可选的。chunk和encoding的含义与write方法类似。callback是一个可选的回调,当你提供它时,它会被关联到Writable的finish事件上,这样当finish事件发射时它就会被调用。

    常用的事件:

    drain事件:当一个流不处在 drain 的状态, 对 write() 的调用会缓存数据块, 并且返回 false。 一旦所有当前所有缓存的数据块都排空了(被操作系统接受来进行输出), 那么 'drain' 事件就会被触发

    finish事件:在调用了 stream.end() 方法,且缓冲区数据都已经传给底层系统之后, 'finish' 事件将被触发。

    我们来写个小例子:

    let fs = require('fs');

    let FileWriteStream = require('./FileWriteStream');

    let ws = FileWriteStream('./2.txt',{

        flags:'w',

        encoding:'utf8',

        highWaterMark:3

    });

    let i = 10;

    function write(){

        let  flag = true;

        while(i&&flag){

            flag = ws.write("1",'utf8',(function(i){

                return function(){

                    console.log(i);

                }

            })(i));

            i--;

            console.log(flag);

        }

    }

    write();

    ws.on('drain',()=>{

        console.log("drain");

        write();

    });

    六,缓存区

    不管是可读流还是可写流都会将数据存储到内部的缓冲器中。

    缓冲器的大小取决于传递给流构造函数的highWaterMark选项。对于普通的流,highWaterMark

    指定了总共的字节数。对于工作在对象模式的流,指定了对象的总数。

    相关文章

      网友评论

          本文标题:对nodejs中流的理解

          本文链接:https://www.haomeiwen.com/subject/eoemzxtx.html