1. 程式人生 > >Node學習基礎(四)之檔案的流操作以及pipe管道簡單舉例

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  會讀一部分,寫一部分,不管檔案有多大,只要時間允許,總會處理完成。