Stream 接口的优势
Stream 接口看起来比 Promise 接口复杂多了,为何还会有这种应用场景呢?
其实在 HTTP 服务领域,Stream 模型会有更大的优势,因为 HTTP 请求本身就是一个 Request Stream,如要将一个上传文件以 gzip 压缩返回,使用 Stream 接口不需要将上传文件保存到本地磁盘,而是直接消费这个文件流。
使用 egg 文件上传的示例代码 ,我们稍微改造一下,就能实现 gzip 压缩然后返回。
const pump = require('pump');class UploadFormController extends Controller {
// ... other codes
async upload() {
const stream = await this.ctx.getFileStream();
// 直接将压缩流赋值给 ctx.body,实现边压缩边返回的流式响应
this.ctx.body = pump(stream, new compressing.gzip.FileStream());
}
}
tar | gzip > tgz
gzip 章节可以提前知道,tar 是负责对文件夹进行打包:package:的。
例如要对 nodejs-compressing-dem o 整个文件夹打包成一个文件发送给别人,可以通过 tar 命令完成。
$ tar -c -f nodejs-compressing-demo.tar nodejs-compressing-demo/$ ls -l nodejs-compressing-demo.tar
-rw-r--r-- 1 a a 206336 Feb 12 14:01 nodejs-compressing-demo.tar
如大家所见,tar 打包出来的文件一般都比较大,因为它是未压缩的,大小跟实际文件夹总大小接近。所以我们都会在打包同时进行压缩。
$ tar -c -z -f nodejs-compressing-demo.tgz nodejs-compressing-demo/$ ls -l nodejs-compressing-demo.tgz
-rw-r--r-- 1 a a 39808 Feb 12 14:07 nodejs-compressing-demo.tgz
tar 和 tgz 超过 5 倍大小的差异,可以大大减少网络传输带宽。
Node.js 实现 tgz
Promise 接口
先使用 compressing.tar.compressDir(sourceDir, targetFile) 将一个文件夹打包到一个 tar 文件,然后使用上文的 gzip 压缩方式,将 tar 文件压缩为 tgz 文件。
const compressing = require('compressing');compressing.tar.compressDir('nodejs-compressing-demo', 'nodejs-compressing-demo.tar')
.then(() => {
return compressing.gzip.compressFile('nodejs-compressing-demo.tar',
'nodejs-compressing-demo.tgz');
});
.then(() => {
console.log('success');
})
.catch(err => {
console.error(err);
});
// 解压缩
compressing.gzip.uncompress('nodejs-compressing-demo.tgz', 'nodejs-compressing-demo.tar')
.then(() => {
return compressing.tar.uncompress('nodejs-compressing-demo.tar',
'nodejs-compressing-demo2');
});
.then(() => {
console.log('success');
})
.catch(err => {









