创建一个文件写入流
fs.createWriteStream(path[, options])
可选填参数
写入
返回值与背压问题
当返回值为true说明管道内还可以添加数据,当为false时说明管道已经满啦, 管道的值由highWaterMark
来规定 ,然而内存处理数据的速度非常快,而硬盘写入速度又慢, 内存会将数据按照highWaterMark
的值将数据分组放进队列等待写入成功,放入一组字节。这样就会产生背压,这样就会浪费内存的储存空间,毕竟内存的储存空间本来就不多。
如图
示例:
const path = require('path');
const fs = require('fs');
const firName = path.resolve(__dirname, './a.txt');
const ws = fs.createWriteStream(firName,{
flags: 'w',
encoding: 'utf-8',
highWaterMark: 16 * 1024,
autoClose: true,
})
/**
* 写入
* 背压问题
* 由于highWaterMark规定啦每次操作的字节数,当达到规定的字节数就开始写入,写入成功才会执行下次写入
* 由于内存处理数据能比硬盘强,故内存会将需要写入的数据进行排队,以highWaterMark规定的字节数为一组
* 而内存中的空间是有限且内空间珍贵,这样会导致背压问题,内存中滞留的啦数据,
*/
const flag = ws.write('aaaa');
console.log(flag)
//当写入队列清空时,会触发drain事件
ws.on('drain', () => {
console.log('写入成功,管道已经清空可以开始写入啦')
})
解决背压
背压问题就是管道满啦,内存还在处理数据,我们可以在管道满时停止处理数据
当管被清空时在让内存处理数据
可以使用事件drain
drain事件
当写入队列清空时,会触发drain事件
这个事件会在每次写入队列清空时触发,也就是硬盘写入成功触发
示例:
/**
* 解决背压问题
* 判断flag,当满足与highWaterMark固定值,flag就会变为flase 此时就暂停写入
* 当管道清空说明写入成功,恢复写入
*/
let i = 0;
function test () {
let flag = true;
while(i < 1024*1024 && flag) {
flag = ws.write('a')
i++;
}
}
test()
ws.on('drain', () => {
console.log('drain')
test()
})
简单做法- pipe(写入流)
读取流中有一个方法 pipe
可以实现读取一点写入一点
代码:
const fs = require('fs')
const patn = require('path')
const readF = patn.resolve(__dirname, './a.txt')
const writeF = patn.resolve(__dirname, './b.txt');
const rs = fs.createReadStream(readF, {
encoding: 'utf8'
})
const ws = fs.createWriteStream(writeF)
/**
* 解决背压, 读一点写一点
*/
rs.pipe(ws)
rs.on('close', () => {
console.log('close')
})