下面演示一些node.js内置的 transform流

  1. const fs = require("fs");
  2. // 引入g-zip压缩模块
  3. const zlib = require("zlib");
  4. const file = process.argv[2]; //第二个参数 也就是用户传的一个路径
  5. fs.createReadStream(file)
  6. .pipe(zlib.createGzip())
  7. .pipe(fs.createWriteStream(file + ".gz"));

创建一个fs读文件的流,去读file。
这个文件可能很大,所以就用流一点一点地读,每读一点就传给gzip去压缩,压缩完之后通过管道再传给一个写文件的流,输出成file.gz文件

就以上几行代码,就可以实现一个g-zip压缩。

尝试运行:
image.png
image.png
就会把一个30k的文件压缩成3k

改进1:加进度条

如果要压缩的文件很大,可以加一个进度条
第十行代码: .on(“data”, () => process.stdout.write(“.”)) 监听g-zip,只要他传出一点数据,就打印出一个点

  1. const fs = require("fs");
  2. // 引入g-zip压缩模块
  3. const zlib = require("zlib");
  4. const file = process.argv[2]; //第二个参数 也就是用户传的一个路径
  5. fs.createReadStream(file)
  6. .pipe(zlib.createGzip())
  7. .on("data", () => process.stdout.write("."))
  8. .pipe(fs.createWriteStream(file + ".gz"))
  9. .on("finish", ()=>{console.log(`done`)})

运行后:
image.png
打印了两个点,说明压缩了两次。

再次改进

  1. const fs = require("fs");
  2. // 引入g-zip压缩模块
  3. const zlib = require("zlib");
  4. const file = process.argv[2]; //第二个参数 也就是用户传的一个路径
  5. const { Transform } = require("stream");
  6. // 一个变换流 拿到数据之后 原封不动地传回给callback
  7. // 意思是 这个流 不改变数据,数据是透传的,但是每次收到数据打印一个点
  8. const reportProgress = new Transform({
  9. transform(chunk, encoding, callback) {
  10. process.stdout.write(".");
  11. callback(null, chunk);
  12. }
  13. });
  14. fs.createReadStream(file)
  15. .pipe(zlib.createGzip())
  16. .on("data", () => process.stdout.write("."))
  17. // .pipe(fs.createWriteStream(file + ".gz"))
  18. .pipe(reportProgress)
  19. .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
要先加密再压缩。 这样的话 解压文件的之后才会得到一个加密文件,否则解压不了。

  1. const fs = require("fs");
  2. const zlib = require("zlib");
  3. //引入nodejs自带的加密模块
  4. const crypto = require('crypto')
  5. const file = process.argv[2]; //第二个参数 也就是用户传的一个路径
  6. const { Transform } = require("stream");
  7. const reportProgress = new Transform({
  8. transform(chunk, encoding, callback) {
  9. process.stdout.write(".");
  10. callback(null, chunk);
  11. }
  12. });
  13. fs.createReadStream(file)
  14. .pipe(crypto.createCipher("aes192", "123456"))
  15. .pipe(zlib.createGzip())
  16. .on("data", () => process.stdout.write("."))
  17. .pipe(fs.createWriteStream(file + ".gz"))
  18. .pipe(reportProgress)
  19. .on("finish", () => { console.log(`done`) })

解密的话使用这个方法的反方法就能解密了,具体看文档。