Node Stream 實例:壓縮文件腳本

Node的數據流模塊配合pipe函數可以生成很多有效的文件處理工具,以下代碼是一個簡單的壓縮文件腳本:

const fs = require('fs');
const zlib = require('zlib');
const { Transform } = require('stream');
const file = process.argv[2];

let src = fs.createReadStream(file);
var stats = fs.statSync(file)
let total = 0;

const reportProgress = new Transform({
    transform(chunk, encoding, callback) {
        total += chunk.length;
        let percentage = Math.floor((total / stats['size']) * 100);
        if (percentage % 5 == 0) console.log(percentage + '%');
        callback(null, chunk);
    }
})

src
    .pipe(zlib.createGzip())
    .pipe(reportProgress)
    .pipe(fs.createWriteStream(file + '.gz'))
    .on('finish', () => console.log('Done!'));

整個腳本可以被拆分成三個部分去理解:

1. 壓縮文件

const fs = require('fs');
const zlib = require('zlib');
const file = process.argv[2];

src
    .pipe(zlib.createGzip())
    .pipe(fs.createWriteStream(file + '.gz'))

壓縮文件邏輯只用六行代碼便可實現。Node原生的zlib模塊屬於duplex數據流,這表示它及可讀也可寫,所以它可以作爲中間的pipe中轉站將src的數據寫入在內後做壓縮處理,然後再被讀取。下一步便是通過fs.createWriteStream將文件寫出。

2. 自定義Transform Stream

const { Transform } = require('stream');

const reportProgress = new Transform({
    transform(chunk, encoding, callback) {
        total += chunk.length;
        let percentage = Math.floor((total / stats['size']) * 100);
        if (percentage % 5 == 0) console.log(percentage + '%');
        callback(null, chunk);
    }
})

Transform數據流基於Duplex數據流也是雙向的,在傳入的對象內需要定於名爲tranform的函數作爲callback。Callback內會傳入三個參數,可以對相應的數據流做處理並需要調用第三個參數"callback"去指向下一段數據流直到所有數據都完成處理。

3. 事件監聽

    .on('finish', () => console.log('Done!'));

所有的數據流都可以通過事件被監聽,其中包括結束事件,所以在拼接pipe的同時也添加了on的來監聽finish事件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章