let fs = require('fs');
let ws = fs.createWriteStream('./2.txt');
let rs = fs.createReadStream('./1.txt');
rs.on('data', data => {
var flag = ws.write(data);
if(!flag)
rs.pause();
});
ws.on('drain', () => {
rs.resume();
});
rs.on('end', () => {
ws.end();
});
6.2 pipe的用法
let from = fs.createReadStream('./1.txt');
let to = fs.createWriteStream('./2.txt');
from.pipe(to);
6.3 unpipe方法
readable.unpipe()方法将之前通过stream.pipe()方法绑定的流分离
let fs = require('fs');
let from = fs.createReadStream('./1.txt');
let to = fs.createWriteStream('./2.txt');
from.pipe(to);
setTimeout(() => {
console.log('关闭向2.txt的写入');
from.unpipe(writable);
console.log('手动关闭可写流');
to.end();
}, 1000);
前言
什么是流呢?看字面意思,我们可能会想起生活中的水流,电流。 但是流不是水也不是电,它只是描述水和电的流动;所以说流是抽象的。 在node.js中流是一个抽象接口,它不关心文件内容,只关注是否从文件中读到了数据,以及读到数据之后的处理,接着看:
1.流的概念
这里说了“所有的流都是EventEmitter的实例” 所以流继承了EventEmitter类。再来看流的类型:
2.流的类型
3.流的数据模式
流中的数据有两种模式,二进制模式和对象模式.
4.可读流(createReadStream)
4.1 创建可读流
这里说说流程:
4.2 可读流的两种模式
在 paused 模式下,必须显式调用 stream.read() 方法来从流中读取数据片段。 在可读流'readable'事件里我们就必须调用stream.read()方法。
4.3 可读流'readable'事件
这里需要明白三点: 先创建一个1.txt
1.当我只要创建一个流 就会先把缓存区 填满,等待着你自己消费 2.当你消费小于 最高水位线时 会自动添加highWaterMark这么多数据
3.如果当前缓存区被清空后会再次触发readable事件
4.4 readable原理图
5.可写流(createWriteStream)
5.1 创建可写流
5.1.1 write方法
5.1.2 end方法
5.1.3 drain方法
drain事件的触发条件,必须满足两个条件: 1.当前缓存区满了,不能再写了 2.缓存区满了后被清空了,才会触发drain事件
6.pipe方法(管道)
我们在开发中可能会遇到,要把可读流读出的数据需要放到可写流中去写入到文件里面,这时就可以用pipe方法
6.1 pipe的原理
pipe方法的原理很简单,就是读一点,写一点,上代码
let fs = require('fs'); let ws = fs.createWriteStream('./2.txt'); let rs = fs.createReadStream('./1.txt'); rs.on('data', data => { var flag = ws.write(data); if(!flag) rs.pause(); }); ws.on('drain', () => { rs.resume(); }); rs.on('end', () => { ws.end(); });
6.2 pipe的用法
let from = fs.createReadStream('./1.txt'); let to = fs.createWriteStream('./2.txt'); from.pipe(to);
6.3 unpipe方法
readable.unpipe()方法将之前通过stream.pipe()方法绑定的流分离
let fs = require('fs'); let from = fs.createReadStream('./1.txt'); let to = fs.createWriteStream('./2.txt'); from.pipe(to); setTimeout(() => { console.log('关闭向2.txt的写入'); from.unpipe(writable); console.log('手动关闭可写流'); to.end(); }, 1000);
7.自定义流
我们可以引入stream模块,想实现什么流 就继承这个流。
7.1 自定义可读流
7.2 自定义可写流
为了实现可写流,我们需要使用流模块中的Writable构造函数。 我们只需给Writable构造函数传递一些选项并创建一个对象。唯一需要的选项是write函数,该函数揭露数据块要往哪里写。
7.3 实现双工流(duplex)
有了双工流,我们可以在同一个对象上同时实现可读和可写,就好像同时继承这两个接口。 重要的是双工流的可读性和可写性操作完全独立于彼此。 net中的Socket就是一个duplex双工流
8.结束语
说到这里,我想大家应该大致了解了node.js里面的流。 之前说过在node里流还是很重要的,http里的request和response都是流。 在下一篇文章我会写一个readStream和writeStream的简单实现。 本人水平有限,有错误的地方希望指出。