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或asp实现的判断身份证号码是否正确两种验证方法
Nov 26 Javascript
一些主流JS框架中DOMReady事件的实现小结
Feb 12 Javascript
PHP abstract与interface之间的区别
Nov 11 Javascript
简介JavaScript中的sub()方法的使用
Jun 08 Javascript
JavaScript节点及列表操作实例小结
Aug 05 Javascript
基于bootstrap风格的弹框插件
Dec 28 Javascript
jQuery插件zTree实现的基本树与节点获取操作示例
Mar 08 Javascript
详解vue事件对象、冒泡、阻止默认行为
Mar 20 Javascript
react native带索引的城市列表组件的实例代码
Aug 08 Javascript
Three.js中网格对象MESH的属性与方法详解
Sep 27 Javascript
js 数组详细操作方法及解析合集
Jun 01 Javascript
解决vue.js提交数组时出现数组下标的问题
Nov 05 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
实时抓取YAHOO股票报价的代码
2006/10/09 PHP
php ignore_user_abort与register_shutdown_function 使用方法
2009/06/14 PHP
PHP分页类集锦
2014/11/18 PHP
PHP文件生成的图片无法使用CDN缓存的解决方法
2015/06/20 PHP
微信支付PHP SDK ―― 公众号支付代码详解
2016/09/13 PHP
Yii框架数据模型的验证规则rules()被执行的方法
2016/12/02 PHP
Yii2表单事件之Ajax提交实现方法
2017/05/04 PHP
thinkPHP框架实现的简单计算器示例
2018/12/07 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
Laravel6.18.19如何优雅的切换发件账户
2020/06/14 PHP
11款基于Javascript的文件管理器
2009/10/25 Javascript
javascript 自动填写表单的实现方法
2010/04/09 Javascript
jquery isType() 类型判断代码
2011/02/14 Javascript
IE6-IE9不支持table.innerHTML的解决方法分享
2012/09/14 Javascript
JS的replace方法详细介绍
2012/11/09 Javascript
javascript中声明函数的方法及调用函数的返回值
2014/07/22 Javascript
JS+CSS实现自动改变切换方向图片幻灯切换效果的方法
2015/03/02 Javascript
jQuery使用fadein方法实现渐出效果实例
2015/03/27 Javascript
前端js弹出框组件使用方法
2020/08/24 Javascript
基于jQuery实现左侧菜单栏可折叠功能
2016/12/27 Javascript
js实现漫天星星效果
2017/01/19 Javascript
简单谈谈gulp-changed插件
2017/02/21 Javascript
Web制作验证码功能实例代码
2017/06/19 Javascript
ES6 javascript中Class类继承用法实例详解
2017/10/30 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
2018/03/06 Javascript
vue项目中应用ueditor自定义上传按钮功能
2018/04/27 Javascript
JS前端广告拦截实现原理解析
2020/02/17 Javascript
Python第三方库的安装方法总结
2016/06/06 Python
详解CSS3媒体查询响应式布局bootstrap 框架原理实战(推荐)
2020/11/16 HTML / CSS
html5给汉字加拼音加进度条的实现代码
2020/04/07 HTML / CSS
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
应聘面试自我评价
2014/01/24 职场文书
2015年国培研修感言
2015/08/01 职场文书
三八节祝酒词
2015/08/11 职场文书
导游词之临安白水涧
2019/11/05 职场文书
Python3 多线程(连接池)操作MySQL插入数据
2021/06/09 Python