下面演示一些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`) })
解密的话使用这个方法的反方法就能解密了,具体看文档。