最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入nodejs中流(stream)的理解

 更新時間:2017年03月27日 09:51:16   作者:chshouyu  
本篇文章主要介紹了深入nodejs中流(stream)的理解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

nodejs的fs模塊并沒有提供一個copy的方法,但我們可以很容易的實現(xiàn)一個,比如:

var source = fs.readFileSync('/path/to/source', {encoding: 'utf8'});
fs.writeFileSync('/path/to/dest', source);

這種方式是把文件內(nèi)容全部讀入內(nèi)存,然后再寫入文件,對于小型的文本文件,這沒有多大問題,比如grunt-file-copy就是這樣實現(xiàn)的。但是對于體積較大的二進制文件,比如音頻、視頻文件,動輒幾個GB大小,如果使用這種方法,很容易使內(nèi)存“爆倉”。理想的方法應該是讀一部分,寫一部分,不管文件有多大,只要時間允許,總會處理完成,這里就需要用到流的概念。

如上面高大上的圖片所示,我們把文件比作裝水的桶,而水就是文件里的內(nèi)容,我們用一根管子(pipe)連接兩個桶使得水從一個桶流入另一個桶,這樣就慢慢的實現(xiàn)了大文件的復制過程。

Stream在nodejs中是EventEmitter的實現(xiàn),并且有多種實現(xiàn)形式,例如:

  • http responses request
  • fs read write streams
  • zlib streams
  • tcp sockets
  • child process stdout and stderr

上面的文件復制可以簡單實現(xiàn)一下:

var fs = require('fs');
var readStream = fs.createReadStream('/path/to/source');
var writeStream = fs.createWriteStream('/path/to/dest');

readStream.on('data', function(chunk) { // 當有數(shù)據(jù)流出時,寫入數(shù)據(jù)
  writeStream.write(chunk);
});

readStream.on('end', function() { // 當沒有數(shù)據(jù)時,關(guān)閉數(shù)據(jù)流
  writeStream.end();
});

上面的寫法有一些問題,如果寫入的速度跟不上讀取的速度,有可能導致數(shù)據(jù)丟失。正常的情況應該是,寫完一段,再讀取下一段,如果沒有寫完的話,就讓讀取流先暫停,等寫完再繼續(xù),于是代碼可以修改為:

var fs = require('fs');
var readStream = fs.createReadStream('/path/to/source');
var writeStream = fs.createWriteStream('/path/to/dest');

readStream.on('data', function(chunk) { // 當有數(shù)據(jù)流出時,寫入數(shù)據(jù)
  if (writeStream.write(chunk) === false) { // 如果沒有寫完,暫停讀取流
    readStream.pause();
  }
});

writeStream.on('drain', function() { // 寫完后,繼續(xù)讀取
  readStream.resume();
});

readStream.on('end', function() { // 當沒有數(shù)據(jù)時,關(guān)閉數(shù)據(jù)流
  writeStream.end();
});

或者使用更直接的pipe

// pipe自動調(diào)用了data,end等事件
fs.createReadStream('/path/to/source').pipe(fs.createWriteStream('/path/to/dest'));

下面是一個更加完整的復制文件的過程

var fs = require('fs'),
  path = require('path'),
  out = process.stdout;

var filePath = '/Users/chen/Movies/Game.of.Thrones.S04E07.1080p.HDTV.x264-BATV.mkv';

var readStream = fs.createReadStream(filePath);
var writeStream = fs.createWriteStream('file.mkv');

var stat = fs.statSync(filePath);

var totalSize = stat.size;
var passedLength = 0;
var lastSize = 0;
var startTime = Date.now();

readStream.on('data', function(chunk) {

  passedLength += chunk.length;

  if (writeStream.write(chunk) === false) {
    readStream.pause();
  }
});

readStream.on('end', function() {
  writeStream.end();
});

writeStream.on('drain', function() {
  readStream.resume();
});

setTimeout(function show() {
  var percent = Math.ceil((passedLength / totalSize) * 100);
  var size = Math.ceil(passedLength / 1000000);
  var diff = size - lastSize;
  lastSize = size;
  out.clearLine();
  out.cursorTo(0);
  out.write('已完成' + size + 'MB, ' + percent + '%, 速度:' + diff * 2 + 'MB/s');
  if (passedLength < totalSize) {
    setTimeout(show, 500);
  } else {
    var endTime = Date.now();
    console.log();
    console.log('共用時:' + (endTime - startTime) / 1000 + '秒。');
  }
}, 500);

可以把上面的代碼保存為copy.js試驗一下

我們添加了一個遞歸的setTimeout(或者直接使用setInterval)來做一個旁觀者,每500ms觀察一次完成進度,并把已完成的大小、百分比和復制速度一并寫到控制臺上,當復制完成時,計算總的耗費時間,效果如圖:

我們復制了一集1080p的權(quán)利的游戲第四季第7集,大概3.78G大小,由于使用了SSD,可以看到速度還是非常不錯的,哈哈哈~ 復制完成后,顯示總花費時間

結(jié)合nodejs的readline, process.argv等模塊,我們可以添加覆蓋提示、強制覆蓋、動態(tài)指定文件路徑等完整的復制方法,有興趣的可以實現(xiàn)一下,實現(xiàn)完成,可以

ln -s /path/to/copy.js /usr/local/bin/mycopy

這樣就可以使用自己寫的mycopy命令替代系統(tǒng)的cp命令

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node使用crypto模塊為用戶密碼加密

    node使用crypto模塊為用戶密碼加密

    本文主要介紹了node使用crypto模塊為用戶密碼加密,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Node.js的HTTP模塊、URL模塊與supervisor工具介紹

    Node.js的HTTP模塊、URL模塊與supervisor工具介紹

    這篇文章介紹了Node.js的HTTP模塊、URL模塊與supervisor工具,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 一文詳解Node.js服務器動態(tài)資源處理

    一文詳解Node.js服務器動態(tài)資源處理

    動態(tài)資源處理也就是對數(shù)據(jù)進行重新排序來讀寫數(shù)據(jù)庫,讀取反序列化,寫入序列化,這篇文章主要來和大家聊聊Node.js中的服務器動態(tài)資源處理,感興趣的可以了解下
    2024-04-04
  • nodejs基于express實現(xiàn)文件上傳的方法

    nodejs基于express實現(xiàn)文件上傳的方法

    這篇文章主要介紹了nodejs基于express實現(xiàn)文件上傳的方法,結(jié)合實例形式分析了nodejs基于express框架實現(xiàn)文件上傳功能的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2018-03-03
  • Sequelize中用group by進行分組聚合查詢

    Sequelize中用group by進行分組聚合查詢

    大家都知道在SQL查詢中,分組查詢是較常用的一種查詢方式。分組查詢是指通過GROUP BY關(guān)鍵字,將查詢結(jié)果按照一個或多個字段進行分組,分組時字段值相同的會被分為一組。在Node.js基于Sequelize的ORM框架中,同樣支持分組查詢,使用非常簡單方便。下面來看看詳細的介紹。
    2016-12-12
  • 深入淺析Node.js 事件循環(huán)、定時器和process.nextTick()

    深入淺析Node.js 事件循環(huán)、定時器和process.nextTick()

    這篇文章主要介紹了Node.js 事件循環(huán)、定時器和process.nextTick()的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-10-10
  • Nodejs連接mysql并實現(xiàn)增、刪、改、查操作的方法詳解

    Nodejs連接mysql并實現(xiàn)增、刪、改、查操作的方法詳解

    這篇文章主要介紹了Nodejs連接mysql并實現(xiàn)增、刪、改、查操作的方法,結(jié)合實例形式詳細分析了nodejs針對mysql數(shù)據(jù)庫的的連接、mysql數(shù)據(jù)庫的創(chuàng)建及nodejs針對mysql增刪改查等相關(guān)操作具體實現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • 使用 Node.js 實現(xiàn)圖片的動態(tài)裁切及算法實例代碼詳解

    使用 Node.js 實現(xiàn)圖片的動態(tài)裁切及算法實例代碼詳解

    這篇文章主要介紹了使用 Node.js 實現(xiàn)圖片的動態(tài)裁切功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09
  • 使用nodejs解析json數(shù)據(jù)

    使用nodejs解析json數(shù)據(jù)

    這篇文章主要介紹了使用nodejs解析json數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • VSCode通過Ctrl+P快速打開node_modules中的文件的操作方法

    VSCode通過Ctrl+P快速打開node_modules中的文件的操作方法

    由于node_modules目錄包含的文件太多,在VSCode中默認情況下是禁止搜索node_modules目錄的,在這種情況下,我們將不得不依次展開node_modules的文件目錄樹,來查找我們所需要的文件,接下來介紹VSCode如何通過Ctrl+P快速打開node_modules中的文件,需要的朋友可以參考下
    2023-07-07

最新評論

文成县| 滕州市| 沛县| 大石桥市| 富源县| 同德县| 平乐县| 中超| 英吉沙县| 黄骅市| 奎屯市| 克拉玛依市| 仙桃市| 化州市| 确山县| 泰和县| 固安县| 蕉岭县| 巴林左旗| 武山县| 河南省| 屯昌县| 钟祥市| 卢龙县| 冕宁县| 铁岭市| 龙门县| 府谷县| 永修县| 盈江县| 根河市| 宜州市| 翁牛特旗| 乐安县| 襄垣县| 日喀则市| 阜南县| 邵东县| 阿巴嘎旗| 瑞昌市| 大冶市|