node stream
stream 分为三种 readable, writable, 或者 both
所有stream都是eventEmitter的实例对象
一个简单的小例子
const http = require('http');
var server = http.createServer( (req, res) => {
// req is an http.IncomingMessage, which is a Readable Stream
// res is an http.ServerResponse, which is a Writable Stream
var body = '';
// we want to get the data as utf8 strings
// If you don't set an encoding, then you'll get Buffer objects
req.setEncoding('utf8');
// Readable streams emit 'data' events once a listener is added
req.on('data', (chunk) => {
body += chunk;
});
// the end event tells you that you have entire body
req.on('end', () => {
try {
var data = JSON.parse(body);
} catch (er) {
// uh oh! bad json!
res.statusCode = 400;
return res.end(`error: ${er.message}`);
}
// write back something interesting to the user:
res.write(typeof data);
res.end();
});
});
server.listen(1337);
// $ curl localhost:1337 -d '{}'
// object
// $ curl localhost:1337 -d '"foo"'
// string
// $ curl localhost:1337 -d 'not json'
// error: Unexpected token o
可读流
一个可读流只有在已经准备好接收数据后,才会发送数据
可读流有两个模式,flowing 和 pause模式
一个正在传送数据,一个停止传送。
切换到flowing模式的三种方法
- 添加data事件处理函数
- 直接显示调用stream.resume()
- 调用stream.pipe();
切换到pause模式的两种方法
- 如果不是使用pipe ,调用stream.pause()
- 如果使用pipe ,清除所有data事件函数。并调用stream.unpipe();
event:close()
当所有的流和资源都关闭时,发送close事件
event:data
当给一个流绑定data事件监听函数时,将把可读流切换到 flowing模式。
var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
console.log('got %d bytes of data', chunk.length);
});
event:end()
当已经没有数据可读取时,end事件将触发。
event:error
event:readable
- 当数据的一部分,可读时,将会触发readable;
- 当内部缓存被传送没了的时候,再来一波数据,将会再次触发。
- 当readable被触发时,暗示着stream有更新,或者被传送完了。
readable.isPaused()
返回是否流被认为强制关闭(stream.pause());
readable.pause();
停止读取缓存。
var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
console.log('got %d bytes of data', chunk.length);
readable.pause();
console.log('there will be no more data for 1 second');
setTimeout(() => {
console.log('now data will start flowing again');
readable.resume();
}, 1000);
});
readable.pipe(destination[, options])
自动控制读写速度,以免内存爆掉的读写方法。
var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt'
readable.pipe(writable);
此方法返会destination流所以使用链式方法。
var r = fs.createReadStream('file.txt');
var z = zlib.createGzip();
var w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);
readable.read([size]);
读取流中的数据,可指定大小。
返回String或Buffer或Null
var readable = getReadableStreamSomehow();
readable.on('readable', () => {
var chunk;
while (null !== (chunk = readable.read())) {
console.log('got %d bytes of data', chunk.length);
}
});
readable.resume()
重新开始读取流。
readable.setEncoding(encoding)
设置流中字符串的编码格式。
var readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', (chunk) => {
assert.equal(typeof chunk, 'string');
console.log('got %d characters of string data', chunk.length);
});