下面演示一些node.js内置的 transform流
const fs = require("fs");// 引入g-zip压缩模块const zlib = require("zlib");const file = process.argv[2]; //第二个参数 也就是用户传的一个路径fs.createReadStream(file).pipe(zlib.createGzip()).pipe(fs.createWriteStream(file + ".gz"));
创建一个fs读文件的流,去读file。
这个文件可能很大,所以就用流一点一点地读,每读一点就传给gzip去压缩,压缩完之后通过管道再传给一个写文件的流,输出成file.gz文件
就以上几行代码,就可以实现一个g-zip压缩。
尝试运行:

就会把一个30k的文件压缩成3k
改进1:加进度条
如果要压缩的文件很大,可以加一个进度条
第十行代码: .on(“data”, () => process.stdout.write(“.”)) 监听g-zip,只要他传出一点数据,就打印出一个点
const fs = require("fs");// 引入g-zip压缩模块const zlib = require("zlib");const file = process.argv[2]; //第二个参数 也就是用户传的一个路径fs.createReadStream(file).pipe(zlib.createGzip()).on("data", () => process.stdout.write(".")).pipe(fs.createWriteStream(file + ".gz")).on("finish", ()=>{console.log(`done`)})
运行后:
打印了两个点,说明压缩了两次。
再次改进
const fs = require("fs");// 引入g-zip压缩模块const zlib = require("zlib");const file = process.argv[2]; //第二个参数 也就是用户传的一个路径const { Transform } = require("stream");// 一个变换流 拿到数据之后 原封不动地传回给callback// 意思是 这个流 不改变数据,数据是透传的,但是每次收到数据打印一个点const reportProgress = new Transform({transform(chunk, encoding, callback) {process.stdout.write(".");callback(null, chunk);}});fs.createReadStream(file).pipe(zlib.createGzip()).on("data", () => process.stdout.write("."))// .pipe(fs.createWriteStream(file + ".gz")).pipe(reportProgress).on("finish", () => { console.log(`done`) })
这个reportProgress变换流,别看它只是收到数据之后只打印一个点,其实是很有用的,他提供了一个位置,让我们可以实现对数据的无限处理。
这就很类似 webpack的loader
一般处理vue文件流程是:
vue-loader => sass-loader => css-loader => postcss-loader => style-loader
使用vue-loader去加载vue文件,加载完成后会给sass-loader处理,然后又交给css-loader处理,一步一步进行下去。
其实就相当于一个变换流,你给我什么数据,我处理完成后变成另外一种数据,然后传给下一个。
改进:加密压缩文件
引入nodejs自带的加密模块:crypto
要先加密再压缩。 这样的话 解压文件的之后才会得到一个加密文件,否则解压不了。
const fs = require("fs");const zlib = require("zlib");//引入nodejs自带的加密模块const crypto = require('crypto')const file = process.argv[2]; //第二个参数 也就是用户传的一个路径const { Transform } = require("stream");const reportProgress = new Transform({transform(chunk, encoding, callback) {process.stdout.write(".");callback(null, chunk);}});fs.createReadStream(file).pipe(crypto.createCipher("aes192", "123456")).pipe(zlib.createGzip()).on("data", () => process.stdout.write(".")).pipe(fs.createWriteStream(file + ".gz")).pipe(reportProgress).on("finish", () => { console.log(`done`) })
解密的话使用这个方法的反方法就能解密了,具体看文档。
