Stream流种类
1、Readable : 可读流 用来提供数据,外部来源的数据会被存储到内部的Buffer里面缓存起来
2、Writable : 可写流,用来消费数据,从Readable里面获取数据之后,对Buffer数据进行处理
3、Duplex : 既可以接收,又可以发送
4、Transform : 转换流,也是可读可写
事件属性大同小异
首先设想一下,请求一张图片数据,在浏览器中显示出来
var http = require('http')
var fs = require('fs')
http
.createServer(function(req, res) {
// fs.readFile('./buffer/timg.jpeg', function(err, data) {
// if(err) {
// res.end('file not exist!')
// }
// else {
// res.writeHeader(200, {'Context_Type': 'text/html'})
// res.end(data)
// }
// })
fs.createReadStream('../buffer/timg.jpeg').pipe(res)
})
.listen(8090)
在控制台node 文件名.js 运行一下
在浏览器上打出localhost:8090,就可以在浏览器中看到我们想要的图片
我们的图片不一定是本地的,我们可以从线上爬取一张图片,然后返回给浏览器
这样我们就要使用request模块
在控制台npm install request
// fs.createReadStream('../buffer/timg.jpeg').pipe(res)
request('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png')
.pipe(res)
再运行一下,就可以看到网络图片了
pipe方法会自动监听data和end事件,图片文件中的每一小段数据都会源源不断的发送给客户端,pipe方法还可以自动控制后段压力,在客户端连接缓慢的时候,node可以将尽可能少的缓存放到内存里面,通过对内存空间的调度,就能自动控制流量,从而避免掉目标被快速读取的可读流所淹没,并且数据在pipe的时候那,只有在pipe末端的目标流珍真正要数据的时候,数据才会取出来。
//拿到可读流构造函数
var Readable = require('stream').Readable
//拿到可写流构造函数
var Writable = require('stream').Writable
//拿到两个实例
var readStream = new Readable()
var writeStream = new Writable()
//添加可读流数据,负责push内容
readStream.push('I')
readStream.push('Love')
readStream.push('Lijixuan')
readStream.push(null)
//可写流负责打印出来读出来这个内容
writeStream._write = function(chunk, encode,cb) {
console.log(chunk.toString())
cb()
}
//可以用pipe连接起来,实现整个数据传递,我们就不用关心数据是怎么流动的
readStream.pipe(writeStream)
最后我们实现一个自己定制的可读流、可写流、转换流
//拿到stream
var stream = require('stream')
//拿到工具类
var util = require('util')
//自己定制一个可写流
function ReadStream() {
//改变上下文,可以调用可读类的方法
stream.Readable.call(this)
}
//让我们声明的可读流继承流里面可读的原型
util.inherits(ReadStream, stream.Readable)
//添加read方法
ReadStream.prototype._read = function() {
this.push('I')
this.push('Love')
this.push('Lijixuan')
this.push(null)
}
//声明可写流,改变上下文
function WritStream() {
stream.Writable.call(this)
this._cached = new Buffer('')
}
//继承原型
util.inherits(WritStream, stream.Writable)
//从写可写流的write方法加下划线是私有方法
WritStream.prototype._write = function (chunk, encode, cb) {
console.log(chunk.toString())
cb()
}
//生命自己的转换流
function TransformStream() {
stream.Transform.call(this)
}
//继承原型
util.inherits(TransformStream, stream.Transform)
//从写transfrom方法
TransformStream.prototype._transform = function(chunk, encode, cb) {
this.push(chunk)
cb()
}
TransformStream.prototype._flush = function(cb) {
this.push('OH Yeah')
cb()
}
//生成实力
var rs = new ReadStream()
var ws = new WritStream()
var ts = new TransformStream()
//独到的数据pipe给转换流,对内容做一额外的定制处理,之后pipe给可写流打印
rs.pipe(ts).pipe(ws)