该示例代码有一个filestream项目,它使用一个转换流来解决
filecompress
项目中的文件大小问题 。和以前一样,它在声明一个继承Transform
的Compress
类之前,接受并验证了输入和输出的文件名:import { createReadStream, createWriteStream } from 'fs';import { Transform } from 'stream';// compression Transformclass Compress extends Transform {constructor(opts) {super(opts);this.chunks = 0;this.lengthOrig = 0;this.lengthNew = 0;}_transform(chunk, encoding, callback) {constdata = https://www.huyubaike.com/biancheng/chunk.toString(),// buffer to stringcontent = data.replace(/n/s+/g,'\n')// trim leading spaces.replace(/\/\/.*?\n/g, '')// remove // comments.replace(/\s+/g, ' ')// remove whitespace.replace(/\/\*.*?\*\//g, '')// remove /* comments */.replace(/<!--.*?-->/g, '')// remove <!-- comments -->.replace(/\s*([<>(){}}[\]])\s*/g, '$1') // remove bracket spaces.trim();this.chunks++;this.lengthOrig += data.length;this.lengthNew += content.length;this.push( content );callback();}}
当一个新的数据块准备好时,_transform
方法被调用 。它以Buffer
对象的形式被接收,并被转换为字符串,被最小化,并使用push()
方法输出 。一旦数据块处理完成,一个callback()
函数就会被调用 。应用程序启动了文件读写流,并实例化了一个新的
compress
对象:// process streamconstreadStream = createReadStream(input),wr// process streamconstreadStream = createReadStream(input),writeStream = createWriteStream(output),compress = new Compress();console.log(`processing ${ input }`)
传入的文件读取流定义了.pipe()
方法,这些方法通过一系列可能(或可能不)改变内容的函数将传入的数据输入 。在输出到可写文件之前,数据通过compress
转换进行管道输送 。一旦流结束,最终on('finish')
事件处理函数就会执行:readStream.pipe(compress).pipe(writeStream).on('finish', () => {console.log(`file size${ compress.lengthOrig }`);console.log(`output${ output }`);console.log(`chunksreadStream.pipe(compress).pipe(writeStream).on('finish', () => {console.log(`file size${ compress.lengthOrig }`);console.log(`output${ output }`);console.log(`chunks${ compress.chunks }`);console.log(`file size${ compress.lengthNew } - saved ${ Math.round((compress.lengthOrig - compress.lengthNew) / compress.lengthOrig * 100) }%`);});
使用任意大小的HTML文件的例子运行项目代码:node filestream.js ./test/example.html ./test/output.html
文章插图
这是对Node.js流的一个小例子 。流处理是一个复杂的话题 , 你可能不经常使用它们 。在某些情况下,像Express这样的模块在引擎盖下使用流 , 但对你的复杂性进行了抽象 。
你还应该注意到数据分块的挑战 。一个块可以是任何大小 , 并以不便的方式分割传入的数据 。考虑对这段代码最小化:
<script type="module">// example scriptconsole.log('loaded');</script>
两个数据块可以依次到达:<script type="module">// example
以及:<script>console.log('loaded');</script>
独立处理每个块的结果是以下无效的最小化脚本:<script type="module">script console.log('loaded');</script>
解决办法是预先解析每个块,并将其分割成可以处理的整个部分 。在某些情况下,块(或块的一部分)将被添加到下一个块的开始 。尽管会出现额外的复杂情况,但是最好将最小化应用于整行 。因为
<!-- -->
和/* */
注释可以跨越不止一行 。下面是每个传入块的可能算法:- 将先前块中保存的任何数据追加到新块的开头 。
- 从数据块中移除任意整个
<!--
到-->
以及/*
到*/
部分 。 - 将剩余块分为两部分 。其中
part2
以发现的第一个<!--
或/*
开始 。如果两者都存在,则从part2
中删除除该符号以外的其他内容 。如果两者都没有找到,则在最后一个回车符处进行分割 。如果没有找到,将推荐阅读
- 原神没有课题的答案任务是什么
- 平价好用的眼影有哪些?2018眼影排行榜十强
- 华为手机要恢复出厂设置的利弊(华为手机恢复出厂设置有问题吗)
- 赛马娘手游特雷森学院特别任务有哪些
- 红米note11和小米11有什么区别_哪款值得入手
- 怎样看电脑配置高低,决定电脑价格的因素有哪些
- 惠普星13air缺点_惠普星13air有哪些问题
- Java:既然有了synchronized,为什么还要提供Lock?
- 原神坎蒂丝天赋升级材料有哪些
- 四年级数学脱式计算题 四年级数学脱式计算题500道