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')