Nodejs基础:stream模块入门介绍与使用

模块概览

nodejs的核心模块,基本上都是stream的的实例,比如process.stdout、http.clientRequest。

对于大部分的nodejs开发者来说,平常并不会直接用到stream模块,只需要了解stream的运行机制即可(非常重要)。

而对于想要实现自定义stream实例的开发者来说,就得好好研究stream的扩展API了,比如gulp的内部实现就大量用到了自定义的stream类型。

来个简单的例子镇楼,几行代码就实现了读取文件内容,并打印到控制台:

const fs = require('fs');

fs.createReadStream('./sample.txt').pipe(process.stdout);

Stream分类

在nodejs中,有四种stream类型:

  • Readable:用来读取数据,比如 fs.createReadStream()
  • Writable:用来写数据,比如 fs.createWriteStream()
  • Duplex:可读+可写,比如 net.Socket()
  • Transform:在读写的过程中,可以对数据进行修改,比如 zlib.createDeflate()(数据压缩/解压)。

Readable Stream

以下都是nodejs中常见的Readable Stream,当然还有其他的,可自行查看文档。

  • http.IncomingRequest
  • fs.createReadStream()
  • process.stdin
  • 其他

例子一:

var fs = require('fs');

fs.readFile('./sample.txt', 'utf8', function(err, content){
    // 文件读取完成,文件内容是 [你好,我是程序猿小卡]
    console.log('文件读取完成,文件内容是 [%s]', content);
});

例子二:

var fs = require('fs');

var readStream = fs.createReadStream('./sample.txt');
var content = '';

readStream.setEncoding('utf8');

readStream.on('data', function(chunk){
    content += chunk;
});

readStream.on('end', function(chunk){
    // 文件读取完成,文件内容是 [你好,我是程序猿小卡]
    console.log('文件读取完成,文件内容是 [%s]', content);
});

例子三:

这里使用了.pipe(dest),好处在于,如果文件

var fs = require('fs');

fs.createReadStream('./sample.txt').pipe(process.stdout);

注意:这里只是原封不动的将内容输出到控制台,所以实际上跟前两个例子有细微差异。可以稍做修改,达到上面同样的效果

var fs = require('fs');

var onEnd = function(){
    process.stdout.write(']');    
};

var fileStream = fs.createReadStream('./sample.txt');
fileStream.on('end', onEnd)

fileStream.pipe(process.stdout);

process.stdout.write('文件读取完成,文件内容是[');

// 文件读取完成,文件内容是[你好,我是程序猿小卡]

Writable Stream

同样以写文件为例子,比如想将hello world写到sample.txt里。

例子一:

var fs = require('fs');
var content = 'hello world';
var filepath = './sample.txt';

fs.writeFile(filepath, content);

例子二:

var fs = require('fs');
var content = 'hello world';
var filepath = './sample.txt';

var writeStram = fs.createWriteStream(filepath);
writeStram.write(content);
writeStram.end();

Duplex Stream

最常见的Duplex stream应该就是net.Socket实例了,在前面的文章里有接触过,这里就直接上代码了,这里包含服务端代码、客户端代码。

服务端代码:

var net = require('net');
var opt = {
    host: '127.0.0.1',
    port: '3000'
};

var client = net.connect(opt, function(){
    client.write('msg from client');  // 可写
});

// 可读
client.on('data', function(data){
    // server: msg from client [msg from client]
    console.log('client: got reply from server [%s]', data);
    client.end();
});

客户端代码:

var net = require('net');
var opt = {
    host: '127.0.0.1',
    port: '3000'
};

var client = net.connect(opt, function(){
    client.write('msg from client');  // 可写
});

// 可读
client.on('data', function(data){
    // lient: got reply from server [reply from server]
    console.log('client: got reply from server [%s]', data);
    client.end();
});

Transform Stream

Transform stream是Duplex stream的特例,也就是说,Transform stream也同时可读可写。跟Duplex stream的区别点在于,Transform stream的输出与输入是存在相关性的。

常见的Transform stream包括zlibcrypto,这里举个简单例子:文件的gzip压缩。

var fs = require('fs');
var zlib = require('zlib');

var gzip = zlib.createGzip();

var inFile = fs.createReadStream('./extra/fileForCompress.txt');
var out = fs.createWriteStream('./extra/fileForCompress.txt.gz');

inFile.pipe(gzip).pipe(out);

相关链接

https://nodejs.org/api/stream.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据

大数据干货系列(五)-Hive总结

Hive总结 一、本质 Hive基于一个统一的查询分析层,通过SQL语句的方式对HDFS上的数据进行查 询、统计和分析。 二、四大特点** • Hive本身不存...

2049
来自专栏MYSQL轻松学

MySQL 8.0.11 (2018-04-19, General Availability)

仅支持通过使用 in-place 方式从 MySQL 5.7 升级到 MySQL 8.0 升级; 不支持从 MySQL 8.0 降级到 MySQL 5....

702
来自专栏偏前端工程师的驿站

ObjectDataSource与GridView配合使用经验总结系列二:分页

  令我使用ObjectDataSource配合GridView显示数据的最重要的原因之一就是ObjectDataSource的分页功能,其实GridView本...

1718
来自专栏乐沙弥的世界

Oracle 分区表

随着表的不断增大,对于新纪录的增加、查找、删除等(DML)的维护也更加困难。对于数据库中的超大型表,可通过把它的数据分成若干个小表,从而简化数据库的管理活动。...

572
来自专栏杨建荣的学习笔记

记一次数据库的分析和优化建议(r6笔记第24天)

数据库的巡检是DBA工作中的一部分,有时候我们还是希望能够在巡检的基础上发现一些潜在的问题,把尽可能多的问题解决在初始阶段。 今天来给大家举一个数据库巡检和性能...

3398
来自专栏数据和云

远程数据库的表超过20个索引的影响

小编寄语 我们都知道,对于通过dblink关联本地表和远程表,远程表的索引个数一般不超过20个,对其本身不会有什么影响。但是当索引个数超过20个的时候,又会发生...

2857
来自专栏Spark学习技巧

phoenix二级索引

二级索引 二级索引是从主键访问数据的正交方式。Hbase中有一个按照字典排序的主键Rowkey作为单一的索引。不按照Rowkey去读取记录都要遍历整张表,然后按...

3369
来自专栏极客慕白的成长之路

MySQL的实战系列:大字段如何优化

除特别注明外,本站所有文章均为慕白博客原创,转载请注明出处来自https://geekmubai.com/programming/747.html

613
来自专栏SpringBoot 核心技术

第七章:使用QueryDSL与SpringDataJPA实现子查询

931
来自专栏大数据学习笔记

Hadoop基础教程-第11章 Hive:SQL on Hadoop(11.5 HQL:DDL数据定义)(草稿)

第11章 Hive:SQL on Hadoop 11.5 HQL:DDL数据定义 HQL中数据定义部分,也就是DDL,主要包括数据库定义和数据表的定义。 前面创...

2099

扫码关注云+社区