对nodejs中流的理解

一,为什么需要流?

        当我们学习一个东西的时候,首先我们要知道为什么要学习?那我们为什么要使用流呢?在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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容