
流的概念
- 流是一组有序的 有起点和有终点的字节数据传输手段
- 不关心文件的整体内容,只关注是否从文件中读到了数据,以及读到数据之后的处理
- 流是一个抽象的接口 被node中的很多对象所实现 比如我们比较熟悉的HTTP服务器request和response对象都是流
可读流createReadStream
fs.createReadStream = function(path, options){
return new ReadStream(path, options)
}
util.inherits(ReadStream, Readable)
实现了stream.Readable接口的对象,将对象数据读取为流数据,为监听data事件后,开始发射数据
let rs = fs.creatReadStream(path, [optins])
// 创建可读流, path为读取文件的路径
rs,setEncoding('utf8') // 设置编码
rs.on('data', function(data){
console.log(data)
rs.pause() // 暂停触发data
rs.resume() // 恢复触发流
})
// 监听data事件 流切换到流动模式 数据尽可能快的读出
rs.on('end', function(){
console.log('读取完成')
})
// 监听end事件 在读取完之后触发
rs.on('error', function(err){
console.log(err)
})
// 监听error事件
rs.on('open', function(err){
console.log(err)
})
rs.on('close', function(err){
console.log(err)
})
可写流createWriteStream
实现了stream.Writeable接口的对象将流数据写入到对象中
fs.createWriteStream = function(path, options) {
return new WriteStream(path, options)
};
util.inherits(WriteStream, Writable)
下边实现一下
let ws = fs.createWriteStream(path, [options])
// 创建一个可写流
ws.write(chunk, [encoding],[callback])
// chunk为写入的数据buffer/string
ws.end(chunk,[encoding],[callback])
// 表明接下来没有数据要被写入 Writable 通过传入可选的 chunk 和 encoding 参数,可以在关闭流之前再写入一段数据 如果传入了可选的 callback 函数,它将作为 'finish' 事件的回调函数
drain方法
- 当一个流不在drain的状态 对write()的调用会缓存数据块 并且会返回false 一旦所有缓存的数据都排空 drain就会被触发
let fs = require('fs');
let ws = fs.createWriteStream('./2.txt',{
flags:'w',
encoding:'utf8',
highWaterMark:3
});
let i = 10;
function write(){
let flag = true;
while(i&&flag){
flag = ws.write("1");
i--;
console.log(flag);
}
}
write();
ws.on('drain',()=>{
console.log("drain");
write();
});
finish
如果调用了stream.end 方法 且缓冲区数据都已经都传给底层系统之后 finish就会触发
let writer = fs.createWriteStream('./2.txt');
for (let i = 0; i < 100; i++) {
writer.write(`hello, ${i}!\n`);
}
writer.end('结束\n');
writer.on('finish', () => {
console.error('所有的写入已经完成!');
});
pipe
pipe的原理
let fs = require('fs')
let ws = fs.createWriteStream('./2.txt')
let rs = fs.createReadStream('./1.txt')
rs.on('data', function (data) {
let flag = ws.write(data);
if(!flag)
rs.pause()
})
ws.on('drain', function () {
rs.resume()
})
rs.on('end', function () {
ws.end()
})
pipe的用法
readStream.pipe(writeStream);
let from = fs.createReadStream('./1.txt');
let to = fs.createWriteStream('./2.txt');
from.pipe(to);
将数据的滞留量限制到一个可接受的水平,以使得不同速度的来源和目标不会淹没可用内存。
实现以下pipe的用法
let fs = require('fs');
let ReadStream = require('./ReadStream');
let rs = ReadStream('./1.txt', {
flags: 'r',
encoding: 'utf8',
highWaterMark: 3
});
let FileWriteStream = require('./WriteStream');
let ws = FileWriteStream('./2.txt',{
flags:'w',
encoding:'utf8',
highWaterMark:3
});
rs.pipe(ws);
option的解释
- flags打开文件要做的操作,默认为'r'
- encoding默认为null
- start开始读取的索引位置
- end结束读取的索引位置(包括结束位置)
- highWaterMark读取缓存区默认的大小64kb