手机版

深入nodejs中流(流)的理解

时间:2021-09-05 来源:互联网 编辑:宝哥软件园 浏览:

nodejs的满量程模块并没有提供一个复制的方法,但我们可以很容易的实现一个,比如:

var source=fs。readfilesync('/path/to/source ',{ encoding : ' utf8 ' });fs。WritefileSync('/path/to/dest ',源);这种方式是把文件内容全部读入内存,然后再写入文件,对于小型的文本文件,这没有多大问题,比如咕噜-文件-副本就是这样实现的。但是对于体积较大的二进制文件,比如音频、视频文件,动辄几个千兆字节大小,如果使用这种方法,很容易使内存"爆仓"。理想的方法应该是读一部分,写一部分,不管文件有多大,只要时间允许,总会处理完成,这里就需要用到流的概念。

如上面高大上的图片所示,我们把文件比作装水的桶,而水就是文件里的内容,我们用一根管子(管道)连接两个桶使得水从一个桶流入另一个桶,这样就慢慢的实现了大文件的复制过程。

溪流在nodejs中是事件发射器的实现,并且有多种实现形式,例如:

超文本传送协议(Hyper Text Transport Protocol的缩写)响应请求满量程读写流zlib流传输控制协议套接字子进程stdout和stderr上面的文件复制可以简单实现一下:

var fs=require(' fs ');var readStream=fs。create readstream('/path/to/source ');var WriteStream=fs。CreateWriteStream('/path/to/dest ');readStream.on('data ',function(chunk) { //当有数据流出时,写入数据writeStream.write(区块);});readStream.on('end ',function() { //当没有数据时,关闭数据流写入流。end();});上面的写法有一些问题,如果写入的速度跟不上读取的速度,有可能导致数据丢失。正常的情况应该是,写完一段,再读取下一段,如果没有写完的话,就让读取流先暂停,等写完再继续,于是代码可以修改为:

var fs=require(' fs ');var readStream=fs。create readstream('/path/to/source ');var WriteStream=fs。CreateWriteStream('/path/to/dest ');readStream.on('data ',function(chunk) { //当有数据流出时,写入数据if(WriteStream。write(chunk)=false){//如果没有写完,暂停读取流readstream。pause();}});writeStream.on('drain ',function() { //写完后,继续读取readstream。resume();});readStream.on('end ',function() { //当没有数据时,关闭数据流写入流。end();});或者使用更直接的管

//管道自动调用了数据,结束等事件fs。CreateReadStream('/path/to/source ').管道(fs。create write stream('/path/to/dest ');下面是一个更加完整的复制文件的过程

var fs=require('fs '),path=require('path '),out=process . stdout var file path='/Users/Chen/Movies/game。的。权力。第四季第七集。1080 p .高清电视。x264-batv。' mkv ';var readStream=fs。createreadstream(文件路径);var WriteStream=fs。CreateWriteStream('文件。mkv’);var stat=fs。stat sync(文件路径);var total size=stat . sizevar passedLength=0;var lastSize=0;var startTime=date。now();readStream.on('data ',function(chunk){ passedLength=chunk。长度;if(WriteStream。write(chunk)==false){ ReadStream。pause();}});readStream.on('end ',function(){ writestream。end();});writeStream.on('drain ',function(){ readstream。resume();});setTimeout(函数show(){ var percent=math。天花板((长度/总尺寸)* 100);var size=数学。ceil(passed length/1000000);var diff=size-LastSize;lastSize=大小;出去。clearline();出去。cursorto(0);out.write('已完成大小' MB ',百分比' %,速度:' diff * 2 ' MB/s ');if(passedLength总大小){ setTimeout(显示,500);} else { var end time=date。now();控制台。log();console.log('共用时:'(结束时间-开始时间)/1000 '秒。');}}, 500);可以把上面的代码保存为copy.js试验一下

我们增加了一个递归setTimeout(或者直接使用setInterval)作为旁观者,每500ms观察一次完成进度,并将完成的大小、百分比和复制速度写入控制台。复制完成后,计算总时间消耗。效果如下:

我们复制了1080p权益游戏第四季第七集的一集,大概3.78G大小。由于使用了SSD,可以看到速度还是很不错的,哈哈哈~拷贝完成后,显示的是花费的总时间

结合nodejs的readline、process.argv等模块,我们可以添加完整的复制方式,比如覆盖提示、强制覆盖、动态指定文件路径等,感兴趣的可以实现,完成的也可以实现。

ln-s/path/to/copy . js/usr/local/bin/支原体,以便您可以使用自己的支原体命令来替换系统的cp命令

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:深入nodejs中流(流)的理解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。