Node.js API详解之 zlib模块用法分析


Posted in Javascript onMay 19, 2020

本文实例讲述了Node.js API详解之 zlib模块用法。分享给大家供大家参考,具体如下:

Node.js API详解之 zlib

zlib模块提供通过 Gzip 和 Deflate/Inflate 实现的压缩功能,可以通过这样使用它:

const zlib = require('zlib');

压缩或者解压数据流(例如一个文件)通过zlib流将源数据流传输到目标流中来完成:

const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('input.txt');
const out = fs.createWriteStream('input.txt.gz');
inp.pipe(gzip).pipe(out);

zlib 可以用来实现对 HTTP 中定义的 gzip 和 deflate 内容编码机制的支持。
HTTP 的 Accept-Encoding 头字段用来标记客户端接受的压缩编码。
注意: 下面给出的示例大幅简化,用以展示了基本的概念。使用 zlib 编码成本会很高, 结果应该被缓存。

// 客户端请求示例
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
const request = http.get({ host: 'example.com',
              path: '/',
              port: 80,
              headers: { 'Accept-Encoding': 'gzip,deflate' } });
request.on('response', (response) => {
 const output = fs.createWriteStream('example.com_index.html');
 switch (response.headers['content-encoding']) {
  // 或者, 只是使用 zlib.createUnzip() 方法去处理这两种情况
  case 'gzip':
   response.pipe(zlib.createGunzip()).pipe(output);
   break;
  case 'deflate':
   response.pipe(zlib.createInflate()).pipe(output);
   break;
  default:
   response.pipe(output);
   break;
 }
});
// 服务端示例
// 对每一个请求运行 gzip 操作的成本是十分高昂的.
// 缓存压缩缓冲区是更加高效的方式.
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
http.createServer((request, response) => {
 const raw = fs.createReadStream('index.html');
 let acceptEncoding = request.headers['accept-encoding'];
 if (!acceptEncoding) {
  acceptEncoding = '';
 }
 // 注意:这不是一个合适的 accept-encoding 解析器.
 // 查阅 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
 if (/\bdeflate\b/.test(acceptEncoding)) {
  response.writeHead(200, { 'Content-Encoding': 'deflate' });
  raw.pipe(zlib.createDeflate()).pipe(response);
 } else if (/\bgzip\b/.test(acceptEncoding)) {
  response.writeHead(200, { 'Content-Encoding': 'gzip' });
  raw.pipe(zlib.createGzip()).pipe(response);
 } else {
  response.writeHead(200, {});
  raw.pipe(response);
 }
}).listen(1337);

Constants(常量)

说明:

这些被定义在 zlib.h 的全部常量同时也被定义在 require('zlib').constants 常量上.
注意: 以前, 可以直接从 require('zlib') 中获取到这些常量, 例如 zlib.Z_NO_FLUSH.
目前仍然可以从模块中直接访问这些常量, 但是不推荐使用.

demo:

const zlib = require('zlib');
// 可接受的 flush 值.
zlib.constants.Z_NO_FLUSH
zlib.constants.Z_PARTIAL_FLUSH
zlib.constants.Z_SYNC_FLUSH
zlib.constants.Z_FULL_FLUSH
zlib.constants.Z_FINISH
zlib.constants.Z_BLOCK
zlib.constants.Z_TREES
// 返回压缩/解压函数的返回值. 发送错误时为负值, 正值用于特殊但正常的事件.
zlib.constants.Z_OK
zlib.constants.Z_STREAM_END
zlib.constants.Z_NEED_DICT
zlib.constants.Z_ERRNO
zlib.constants.Z_STREAM_ERROR
zlib.constants.Z_DATA_ERROR
zlib.constants.Z_MEM_ERROR
zlib.constants.Z_BUF_ERROR
zlib.constants.Z_VERSION_ERROR
// 压缩等级.
zlib.constants.Z_NO_COMPRESSION
zlib.constants.Z_BEST_SPEED
zlib.constants.Z_BEST_COMPRESSION
zlib.constants.Z_DEFAULT_COMPRESSION
// 压缩策略
zlib.constants.Z_FILTERED
zlib.constants.Z_HUFFMAN_ONLY
zlib.constants.Z_RLE
zlib.constants.Z_FIXED
zlib.constants.Z_DEFAULT_STRATEGY

Options

说明:

每一个类都有一个 options 对象. 所有的选项都是可选的.
注意:一些选项只与压缩相关, 会被解压类忽视.

demo:

const zlib = require('zlib');
const Options = {
 flush: zlib.constants.Z_NO_FLUSH,
 finishFlush: zlib.constants.Z_FINISH,
 chunkSize: 16*1024,
 windowBits 2, //值在8..15的范围内,这个参数的值越大,内存使用率越高,压缩效果越好。如果使用deflateInit,则默认值为15
 level: 6,  //(压缩级别,值在0-9之间,1速度最快,9压缩比最大,各自折中取值6较为合适。仅压缩有效)
 memLevel: 8,  // (指定多少内存应该内部压缩状态进行分配,1是最小内存速度慢压缩比低。9是最大内存,速度最快。默认值为8。仅压缩有效)
 strategy: 7, // (用于调整压缩算法,仅压缩有效)
 dictionary: ' | | ',  // (仅解压有效,默认值为空字典)
 info: true  //(如果true,返回一个buffer对象和engine)
}

zlib.constants

说明:

提供一个列举出 Zlib 相关常数的对象。

demo:

const zlib = require('zlib');
console.log(zlib.constants);
// { Z_NO_FLUSH: 0,
//  Z_PARTIAL_FLUSH: 1,
//  Z_SYNC_FLUSH: 2,
//  Z_FULL_FLUSH: 3,
//  Z_FINISH: 4,
//  Z_BLOCK: 5,
//  Z_OK: 0,
//  Z_STREAM_END: 1,
//  Z_NEED_DICT: 2,
//  Z_ERRNO: -1,
//  Z_STREAM_ERROR: -2,
//  Z_DATA_ERROR: -3,
//  Z_MEM_ERROR: -4,
//  Z_BUF_ERROR: -5,
//  Z_VERSION_ERROR: -6,
//  Z_NO_COMPRESSION: 0,
//  Z_BEST_SPEED: 1,
//  Z_BEST_COMPRESSION: 9,
//  Z_DEFAULT_COMPRESSION: -1,
//  Z_FILTERED: 1,
//  Z_HUFFMAN_ONLY: 2,
//  Z_RLE: 3,
//  Z_FIXED: 4,
//  Z_DEFAULT_STRATEGY: 0,
//  ZLIB_VERNUM: 4784,
//  DEFLATE: 1,
//  INFLATE: 2,
//  GZIP: 3,
//  GUNZIP: 4,
//  DEFLATERAW: 5,
//  INFLATERAW: 6,
//  UNZIP: 7,
//  Z_MIN_WINDOWBITS: 8,
//  Z_MAX_WINDOWBITS: 15,
//  Z_DEFAULT_WINDOWBITS: 15,
//  Z_MIN_CHUNK: 64,
//  Z_MAX_CHUNK: Infinity,
//  Z_DEFAULT_CHUNK: 16384,
//  Z_MIN_MEMLEVEL: 1,
//  Z_MAX_MEMLEVEL: 9,
//  Z_DEFAULT_MEMLEVEL: 8,
//  Z_MIN_LEVEL: -1,
//  Z_MAX_LEVEL: 9,
//  Z_DEFAULT_LEVEL: -1 }

zlib.createDeflate(options)

说明:

创建并返回一个带有给定 options 的新的 Deflate 对象。
可以使用 deflate 压缩数据。

demo:

const zlib = require('zlib');
const deflate = zlib.createDeflate();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(deflate) );
// Deflate {
//  _readableState:
//  ReadableState { ... },
//  bytesRead: 0,
//  _handle: Zlib { jsref: [Circular], onerror: [Function: zlibOnError] },
//  _hadError: false,
//  _writeState: Uint32Array [ 0, 0 ],
//  _outBuffer: ,
//  _outOffset: 0,
//  _level: -1,
//  _strategy: 0,
//  _chunkSize: 16384,
//  _flushFlag: 0,
//  _scheduledFlushFlag: 0,
//  _origFlushFlag: 0,
//  _finishFlushFlag: 4,
//  _info: undefined }

zlib.createInflate(options)

说明:

创建并返回一个带有给定 options 的新的 Inflate 对象。
Inflate 用于解压一个 deflate 流。

demo:

const zlib = require('zlib');
const deflate = zlib.createDeflate();
const inflate = zlib.createInflate();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(deflate).pipe(inflate) );

zlib.createDeflateRaw(options)

说明:

创建并返回一个带有给定 options 的新的 DeflateRaw 对象.
使用 deflate 压缩数据,并且不附加一个 zlib 头。

demo:

const zlib = require('zlib');
const deflateRaw = zlib.createDeflateRaw();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(deflateRaw) );

zlib.createInflateRaw(options)

说明:

创建并返回一个带有给定 options 的新的 InflateRaw 对象。
InflateRaw 用于解压一个 raw deflate 流。

demo:

const zlib = require('zlib');
const deflateRaw = zlib.createDeflateRaw();
const inflateRaw = zlib.createInflateRaw();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(deflateRaw).pipe(inflateRaw) );

zlib.createGzip(options)

说明:

创建并返回一个带有给定 options 的新的 Gunzip 对象。
使用 gzip 压缩数据。

demo:

const zlib = require('zlib');
const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(gzip) );

zlib.createGunzip(options)

说明:

创建并返回一个带有给定 options 的新的 Gunzip 对象
使用Gunzip解压缩 gzip 流。

demo:

const zlib = require('zlib');
const gzip = zlib.createGzip();
const gunzip = zlib.createGunzip();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(gzip).pipe(gunzip) );

zlib.createUnzip(options)

说明:

创建并返回一个带有给定 options 的新的 Unzip 对象。
Unzip 对象通过自动检测头信息解压 Gzip 或者 Deflate 压缩的流.

demo:

const zlib = require('zlib');
const gzip = zlib.createGzip();
const unzip = zlib.createUnzip();
const fs = require('fs');
const inp = fs.createReadStream('a.js');
console.log( inp.pipe(gzip).pipe(unzip) );

Convenience Methods(简便用法)

说明:

上面我们介绍了各个压缩类的使用。下面介绍一些对应的简便用法。
所有这些方法都将 Buffer, [TypeArray], DataView, 或者字符串作为第一个 参数,
一个回调函数作为可选的第二个参数提供给 zlib 类, 会在 callback(error, result) 中调用.
每一个方法相对应的都有一个接受相同参数, 但是没有回调的 *Sync 版本.
zlib.deflate(buffer [,options],callback)
zlib.deflateSync(buffer [,options])
zlib.inflate(buffer [,options],callback)
zlib.inflateSync(buffer [,options])
zlib.deflateRaw(buffer [,options],callback)
zlib.deflateRawSync(buffer [,options])
zlib.inflateRaw(buffer [,options],callback)
zlib.inflateRawSync(buffer [,options])
zlib.gzip(buffer [,options],callback)
zlib.gzipSync(buffer [,options])
zlib.gunzip(buffer [,options],callback)
zlib.gunzipSync(buffer [,options])
zlib.unzip(buffer [,options],callback)
zlib.unzipSync(buffer [,options])

使用方式如下:

demo:

const input = '.................................';
zlib.deflate(input, (err, buffer) => {
 if (!err) {
  console.log(buffer.toString('base64'));
 } else {
  // 错误处理
 }
});
const buffer = Buffer.from('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, (err, buffer) => {
 if (!err) {
  console.log(buffer.toString());
 } else {
  // 错误处理
 }
});

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
Javascript 中的 && 和 || 使用小结
Apr 25 Javascript
javascript parseInt() 函数的进制转换注意细节
Jan 08 Javascript
document.getElementBy("id")与$("#id")有什么区别
Sep 22 Javascript
JavaScript中一个奇葩的IE浏览器判断方法
Apr 16 Javascript
JS实现从顶部下拉显示的带动画QQ客服特效代码
Oct 24 Javascript
jquery表单插件Autotab使用方法详解
Jun 24 Javascript
JQuery获取鼠标进入和离开容器的方向
Dec 29 Javascript
基于JavaScript实现购物车功能
Feb 07 Javascript
js最实用string(字符串)类型的使用及截取与拼接详解
Apr 26 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
Dec 01 Javascript
JS实现吸顶特效
Jan 08 Javascript
使用vue引入maptalks地图及聚合效果的实现
Aug 10 Javascript
微信jssdk踩坑之签名错误invalid signature
May 19 #Javascript
JavaScript实现简单的弹窗效果
May 19 #Javascript
js实现自定义右键菜单
May 18 #Javascript
微信小程序手动添加收货地址省市区联动
May 18 #Javascript
怎么理解wx.navigateTo的events参数使用详情
May 18 #Javascript
django简单的前后端分离的数据传输实例 axios
May 18 #Javascript
vue+koa2搭建mock数据环境的详细教程
May 18 #Javascript
You might like
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
支持中文的php加密解密类代码
2011/11/27 PHP
PHP微信企业号开发之回调模式开启与用法示例
2017/11/25 PHP
laravel中短信发送验证码的实现方法
2018/04/25 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
2020/04/14 PHP
加速IE的Javascript document输出的方法
2010/12/02 Javascript
js一般方法改写成面向对象方法的无限级折叠菜单示例代码
2013/07/04 Javascript
导航跟随滚动条置顶移动示例代码
2013/09/11 Javascript
如何在指定的地方插入html内容和文本内容
2013/12/23 Javascript
jquery操作select大全
2014/04/25 Javascript
JavaScript不使用prototype和new实现继承机制
2014/12/29 Javascript
jquery捕捉回车键及获取checkbox值与异步请求的方法
2015/12/24 Javascript
Bootstrap CSS使用方法
2016/12/23 Javascript
详解Vue前端生产环境发布配置实战篇
2019/05/07 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
VUE.CLI4.0配置多页面入口的实现
2019/11/25 Javascript
原生js实现自定义难度的扫雷游戏
2021/01/22 Javascript
Python的装饰器模式与面向切面编程详解
2015/06/21 Python
实用自动化运维Python脚本分享
2018/06/04 Python
python实现按长宽比缩放图片
2018/06/07 Python
python使用turtle绘制分形树
2018/06/22 Python
python的sorted用法详解
2019/06/25 Python
使用python打印十行杨辉三角过程详解
2019/07/10 Python
python使用gdal对shp读取,新建和更新的实例
2020/03/10 Python
Python实现AI换脸功能
2020/04/10 Python
Subside Sports德国:足球球衣和球迷商品
2019/06/08 全球购物
叙述DBMS对数据控制功能有哪些
2016/06/12 面试题
校长竞聘演讲稿
2014/05/16 职场文书
水污染治理工程专业求职信
2014/06/14 职场文书
2015年青年志愿者协会工作总结
2015/04/27 职场文书
新年晚会开场白
2015/05/29 职场文书
大学生安全教育主题班会
2015/08/12 职场文书
判断Python中的Nonetype类型
2021/05/25 Python
MySql存储过程之逻辑判断和条件控制
2021/05/26 MySQL
Flask使用SQLAlchemy实现持久化数据
2021/07/16 Python
Java Spring Boot请求方式与请求映射过程分析
2022/06/25 Java/Android