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

深入nodejs中流(stream)的理解

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

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

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

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

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

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

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

上面的文件復(fù)制可以簡(jiǎn)單實(shí)現(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) { // 當(dāng)有數(shù)據(jù)流出時(shí),寫(xiě)入數(shù)據(jù)
  writeStream.write(chunk);
});

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

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

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

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

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

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

或者使用更直接的pipe

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

下面是一個(gè)更加完整的復(fù)制文件的過(guò)程

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('共用時(shí):' + (endTime - startTime) / 1000 + '秒。');
  }
}, 500);

可以把上面的代碼保存為copy.js試驗(yàn)一下

我們添加了一個(gè)遞歸的setTimeout(或者直接使用setInterval)來(lái)做一個(gè)旁觀者,每500ms觀察一次完成進(jìn)度,并把已完成的大小、百分比和復(fù)制速度一并寫(xiě)到控制臺(tái)上,當(dāng)復(fù)制完成時(shí),計(jì)算總的耗費(fèi)時(shí)間,效果如圖:

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

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

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

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node使用crypto模塊為用戶(hù)密碼加密

    node使用crypto模塊為用戶(hù)密碼加密

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

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

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

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

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

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

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

    Sequelize中用group by進(jìn)行分組聚合查詢(xún)

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

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

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

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

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

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

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

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

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

    VSCode通過(guò)Ctrl+P快速打開(kāi)node_modules中的文件的操作方法

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

最新評(píng)論

新龙县| 铜梁县| 比如县| 旺苍县| 唐海县| 万荣县| 绥滨县| 红安县| 益阳市| 龙里县| 大方县| 广汉市| 洛阳市| 阿坝县| 沅陵县| 霍山县| 永安市| 建德市| 济南市| 德安县| 鄂伦春自治旗| 延安市| 大荔县| 济源市| 泗水县| 仙居县| 卓资县| 蓬安县| 木兰县| 宁武县| 武冈市| 侯马市| 什邡市| 清河县| 邵阳县| 宜兰县| 都江堰市| 华安县| 海淀区| 张家界市| 新平|