创建一个文件写入流
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')})
