fs与流均可以处理文件,为何还要用流:node
fs模块处理文件的缺点:将文件的数据全读到内存中,在把数据写到文件内,会大量占用内存数组
流:缓存
Node.js 中有四种基本的流类型:服务器
Writable
- 可写入数据的流(例如 fs.createWriteStream()
)。Readable
- 可读取数据的流(例如 fs.createReadStream()
)。Duplex
- 可读又可写的流(例如 net.Socket
)。Transform
- 在读写过程当中能够修改或转换数据的 Duplex
流(例如 zlib.createDeflate()
)。
可读流:异步
let fs = require('fs') //参数1:要读取的文件 //参数2:配置项,有highWaterMark 每次能读取多少,默认是64k,一次读取64k 不须要更改 let rs = fs.createReadStream('1.txt', { // 返回了一个可读流的实例 flags: 'r' //对文件进行何种操做 encoding: 'utf-8' //设置以后,读取的是字符串,否则默认为buffer start:3 //从索引3开始读 end:7 // 读到索引为7的 包括结束 highWaterMark: 1 }) // 默认是不会把读取的文件给你 须要监听事件,数据到来的事件 rs.emit('data',数据); // 因此把那个绑定这个事件 fs.on('data',function(chunk){ console,log(chunk) }) // 默认这个data事件不停的触发,直到文件中的数据所有读完 rs.on('end', function () { })
let rs = fs,createReadStream('1.txt', {highWaterMark: 1}) let arr = [] rs.on('data',function(chunk){ arr.push(chunk) //读取文件时,是buffer类型,将每次读取的buffer拼到一个数组内 }) // 当文件所有读完,触发end res.end('end',function(){ let filesData = Buffer.concat(arr).toString() }) //报错是 触发err 文件不存在,会触发这个事件 rs.on('err', function(err){ })
若是想要控制读取的速度,能够用rs.pause() 暂停data事件的触发, rs.resume() 恢复data事件的触发函数
let arr = [] rs.on('data',function(chunk){ arr.push(chunk) rs.pause() //暂停 setTimeout(()=>{ rs.resume //一秒恢复一次 data事件的触发,直到数据读完 },1000) }) rs.on('end', ()=>{ console.log(Buffer.concat(arr).toString()) })
可写流:ui
const fs = require('fs') //第一个参数,写入的文件位置 名称 // 第二参数,配置项 let ws = fs.createWriteStream('./a.txt', { flags:'w' highWaterMark:2 }) var flag = ws.write('1', function(){}) //flag为true //write 写的内容,必须是 字符串或者buffer, // 会返回一个布尔值,提示是否还有空间写入, 与highWaterMark对应,例如为写入1时,第一次写 返回一个true,表示还有空间写入 //write是异步的 有回调函数,可是不经常使用 var flag = ws.write('2', function(){}) //flag为false var flag = ws.write('3', function(){}) // 当数据写入文件后,又有空间继续写入时,触发drain事件 ws.on('drain',function(){ }) // 当全部文件写完以后,触发end,也能够在end时,在写入最后的数据 ws.end('结束写入')
const fs = require('fs') function pipe(readFile,writeFileu){ let rs = fs.createReadStream(readFile,{ highWaterMark:5 }) let ws = fs.createWriteStream(writeFileu,{ highWaterMark:1 }) rs.on('data',function(chunk){ console.log('读取') // 当ws.write() 返回false时,表示没有空间继续写入了,暂停读取 if(ws.write(chunk) == false){ rs.pause() // 暂停rs的data事件 } }) // 当触发可写流的drain,表示有空间继续写入了,继续读取文件 ws.on('drain',function(){ rs.resume() // 恢复rs的data事件 // 把当前读入的内容都写到文件中了,继续调用读写 }) // 当读取流触发end方法,表示读取完毕,这时关闭可写流的写入 rs.on('end',function(){ ws.end() }) } pipe('1.txt','./2.txt')