Node學習基礎(四)之檔案的流操作以及pipe管道簡單舉例
舉例說明:
// 1.引入模組 let fs =require('fs'); //2.建立讀入流 let rs = fs.createReadStream('D:/Pictures/Saved Pictures/testSP.mp4'); //要讀取視訊的位置 let ws = fs.createWriteStream('testSP.mp4'); //視屏要寫入的位置,我這裡是預設的專案資料夾下的 //3.監聽流的開啟和關閉 ws.once('open' ,()=>{ console.log("讀入通道開啟"); }); ws.once('close' ,()=>{ console.log("讀入通道以關閉"); }); rs.once('open' ,()=>{ console.log("寫出通道已開啟"); }); rs.once('close' ,()=>{ console.log("寫出通道已關閉"); }); //4.繫結data rs.on("data", (data)=>{ ws.write(data); });
如上程式碼 ,會把一個從本地通過流操作讀寫入專案
這個過程就是先引入模組建立讀入 根據官網的文件 格式就是這樣的 不懂的可以直接看node官方文件
這裡重點解釋一下 once,open,close和 on待會兒再說pipe管道
.once ('事件名‘,回撥函式) ---相當於 bind,但是不會觸發
.once ('事件名‘,function(){})
我們這裡傳入的就是open而且 fs.ReadStream準備好了 碰見open後觸發回撥函式
Es6 語法就是.once('事件名',()=>{ })
.on(字串event, 回撥函式)
.on(event, listener)
為指定事件註冊一個監聽器,接受一個字串 event 和一個回撥函式。
所以遇見close就相當於關閉訊號發出去了等待執行關閉
而碰見open就是WriteStream寫入流被觸發而進行寫入
結合官方文件,我們可以把pipe
方法的主要功能分解為:
- 不斷從來源可讀流中獲得一個指定長度的資料。
- 將獲取到的資料寫入目標可寫流。
- 平衡讀取和寫入速度,防止讀取速度大大超過寫入速度時,出現大量滯留資料。
每當在stream.pipe()
可讀流上呼叫方法時,就會發出此訊息,並將此可寫入新增到其目標集。
//官方文件舉例
var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('pipe', (src) => {
console.error('something is piping into the writer');
assert.equal(src, reader);
});
reader.pipe(writer);
如果看不懂這個 我用剛才的例子改變一下 你們就能理解了
// 1.引入模組
let fs =require('fs');
var request = require('request');
//2.建立讀入流
let rs = fs.createReadStream('D:/Pictures/Saved Pictures/testSP.mp4'); //要讀取視訊的位置
let ws = fs.createWriteStream('testSP.mp4'); //視屏要寫入的位置
//建立管道
rs.pipe(ws);
這裡和最上面的程式碼對比 這裡從寫入位置之後就沒有那麼多繁瑣的程式碼了
而使用pipe的效果和最初的讀入效果完全一樣沒有任何區別 讀入的損失都無差距
在這裡其實 stream.on 是有缺點的,這種方式是把檔案內容全部讀入記憶體,然後再寫入檔案,對於小型的文字檔案,這沒有多大問題,比如 grunt-file-copy 就是這樣實現的。但是對於體積較大的二進位制,比如音訊、視訊檔案,動輒幾個GB大小,如果使用這種方法,很容易使記憶體“爆倉”。理想的方法應該是讀一部分,寫一部分,不管檔案有多大,只要時間允許,總會處理完成,這裡就需要用到流的概念。
而使用pipe 會讀一部分,寫一部分,不管檔案有多大,只要時間允許,總會處理完成。