Node Stream handbook 笔记
来源:互联网 发布:js中数组添加元素 编辑:程序博客网 时间:2024/05/17 21:50
Node Stream handbook 笔记
什么是stream
这里这么理解:数据流是水,而对数据的处理工具是管道,水从管道入口流进,经过管道的处理,从出口流出,多个管道可以串联起来。
如果不用流,我们的代码可能是这样的:
```
var server = http.createServer(function (req, res) {
fs.readFile(__dirname + '/data.txt', function (err, data) {
res.end(data);
});
});
```
这里有一个重要问题就是,只有把整个 `data.txt` 文件内容全部读入内存之后才会触发回调,对于大文件,很可能是无法完整读入内存的,即便是不大的文件,这也是对内存的浪费。
那么用 stream 之后我们可以这样写:
```
var stream = fs.createReadStream(__dirname + '/data.txt');
stream.pipe(res);
```
这样不仅没有回调的嵌套,而且 `pipe` 函数会自动处理 `data` 和 `end` 事件,这里不会把 `data.txt` 文件整个读入内存,而是每当读取一个数据片段的时候就会自动 `pipe` 给 `res` 对象进行处理。
事实上 `pipe` 方法不但能分段处理数据流,而且他还可以自动调节性能。
这样如果我们需要压缩数据就很简单,我们只需要再接一根管子就行了:
```
var stream = fs.createReadStream(__dirname + '/data.txt');
stream.pipe(oppressor(req)).pipe(res);
```
使用stream处理数据的时候,我们可以灵活的把不同的水管连接起来以达到自己的目的。
## Stream 常见类型
常见的是:Readable,Writable,Transform
pipe
任何一种流,都会用 `pipe` 方法来实现输入和输出。
```
src.pipe(dest)
```
Readable
Readable 可以产生数据流:
```
readable.pipe(dest)
```
我们可以通过 `push` 方法向一个 `Readable` 流中添加数据:
```
var Readable = require('stream').Readable;
var rs = new Readable;
rs.push('beep ');
rs.push('boop\n');
rs.push(null);
rs.pipe(process.stdout);
```
根据流的思想,我们不应该是一下把数据全部塞进去才开始读,应该是一边塞数据,一遍可以读。
我们可以通过添加一个 `_read` 方法来向 `Readable` 中推送数据。
```
var Readable = require('stream').Readable;
var rs = Readable();
var c = 97;
rs._read = function () {
rs.push(String.fromCharCode(c++));
if (c > 'z'.charCodeAt(0)) rs.push(null);
};
rs.pipe(process.stdout);
```
除了将 readable直接pipe到另一个流中,我们也可以自己读取数据:
```
var Readable = require('stream').Readable;
var rs = Readable();
var c = 97;
rs._read = function () {
rs.push(String.fromCharCode(c++));
if (c > 'z'.charCodeAt(0)) rs.push(null);
};
rs.on('readable', function () {
var buf = rs.read();
console.log(buf.toString());
});
```
当 `readable` 流准备好数据之后,会触发 `readable` 事件,监听此事件就可以。
如果我们一次读的数据太多,希望塞回去一点怎么办,我们可以用 `unshift`。比如我们希望一次处理一个单词:
```
var Readable = require('stream').Readable;
var rs = new Readable();
rs.push("dog boy girl cat");
rs.push(null);
rs.on('readable', function () {
var buf = rs.read();
console.log("hello:" + buf.toString());
});
```
结果一下全部处理完了。
那么我们可以用unshift来塞回去:
```
var Readable = require('stream').Readable;
var rs = new Readable();
rs.push("dog boy girl cat");
rs.push(null);
rs.on('readable', function () {
var buf = rs.read(),
offset = 0;
for (; offset < buf.length; offset++) {
if (buf[offset].toString() == "32") {
console.log("hello:" + buf.slice(0, offset));
break;
}
}
rs.unshift(buf.slice(offset));
});
```
事实证明上面这样写是塞不回去的。。。为毛。。。
Writable
Writable 是一个只进不出的流:
```
src.pipe(writableStream);
```
对 writable 流,只需要定义一个 `_write` 方法,就可以将一个 readable 流导入其中。我们借用上面的 `readable` 流,把它的结果导入 `writable` 流总
```
var Readable = require('stream').Readable;
var rs = Readable();
var c = 97;
rs._read = function () {
rs.push(String.fromCharCode(c++));
if (c > 'z'.charCodeAt(0)) rs.push(null);
};
var Writable = require('stream').Writable;
var ws = Writable();
ws._write = function (chunk, enc, next) {
console.log(chunk.toString());
next();
};
rs.pipe(ws);
```
我们可以通过调用 `write` 方法向里面写入内容
```
ws.write('beep ');
setTimeout(function () {
ws.end('boop\n');
}, 1000);
```
Transform
0 0
- Node Stream handbook 笔记
- Node.js10 stream接口
- Node.js Stream(流)
- Node:初识Stream
- node.js Stream
- node.js stream I
- node.js stream
- Node.js Stream(流)
- Node.js Stream(流)
- Node.js Stream(流)
- Node.js Stream(流)
- Node.js stream模块
- [Node.js]Stream
- [Node.js]Stream
- [Node.js]Stream
- [Node.js]Stream
- node stream 流操作
- Node.js Stream(流)
- rails常见命令
- ruby元编程——对象模型
- Windows 10 技术预览
- ruby元编程——代码块
- 在WAMPSERVER下增加多版本的PHP(原博客改良版)
- Node Stream handbook 笔记
- ruby元编程——类定义
- 怎样用hibernate的hql查询查询成map或list
- 写给自己的First,希望坚持下去
- 开发日志 PHP连接mysql数据库
- 面试中常见的问题
- 初探treap
- JSP内置对象
- ruby元编程——编写代码的代码