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:以前写的xmlhttp池,代码
May 18 Javascript
JavaScript 私有成员分析
Jan 13 Javascript
js 中的switch表达式使用示例
Jun 03 Javascript
JS去掉第一个字符和最后一个字符的实现代码
Feb 20 Javascript
js 删除数组的几种方法小结
Feb 21 Javascript
JS制作手机端自适应缩放显示
Jun 11 Javascript
Javascript 获取鼠标当前的位置实现方法
Oct 27 Javascript
JS中静态页面实现微信分享功能
Feb 06 Javascript
简单实现js点击展开二级菜单功能
May 16 Javascript
bootstrap table实现iview固定列的效果实例代码详解
Sep 30 Javascript
JS 数组和对象的深拷贝操作示例
Jun 06 Javascript
nuxt.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
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
PHP数组和explode函数示例总结
2015/05/08 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
学习YUI.Ext 第七天--关于View&JSONView
2007/03/10 Javascript
JavaScript 加号(+)运算符号
2009/12/06 Javascript
JavaScript 类的定义和引用 JavaScript高级培训 自定义对象
2010/04/27 Javascript
nodejs入门详解(多篇文章结合)
2012/03/07 NodeJs
jquery中邮箱地址 URL网站地址正则验证实例代码
2013/09/15 Javascript
jquery动态调整div大小使其宽度始终为浏览器宽度
2014/06/06 Javascript
CSS javascript 结合实现悬浮固定菜单效果
2015/08/23 Javascript
深入浅析react native es6语法
2015/12/09 Javascript
详解Vuex中mapState的具体用法
2017/09/28 Javascript
基于jQuery实现定位导航位置效果
2017/11/15 jQuery
浅谈layui 表单元素的选中问题
2019/10/25 Javascript
[03:02]辉夜杯主赛事第二日 每日之星
2015/12/27 DOTA
[01:31]DOTA2上海特级锦标赛 SECRET战队完整宣传片
2016/03/16 DOTA
[58:18]2018DOTA2亚洲邀请赛3月29日 小组赛B组 iG VS Mineski
2018/03/30 DOTA
[01:13:46]iG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python面向对象之反射/自省机制实例分析
2018/08/24 Python
python儿童学游戏编程知识点总结
2019/06/03 Python
python3实现猜数字游戏
2020/12/07 Python
Python+Selenium使用Page Object实现页面自动化测试
2019/07/14 Python
python子线程退出及线程退出控制的代码
2019/10/16 Python
HTML5中判断用户是否正在浏览页面的方法
2014/05/03 HTML / CSS
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
英国最大的婴儿监视器网上商店:Baby Monitors Direct
2018/04/24 全球购物
工程力学专业毕业生求职信
2013/10/06 职场文书
学校卫生检查制度
2014/02/03 职场文书
小学绿色学校申报材料
2014/08/23 职场文书
群众路线专项整治工作情况报告
2014/10/28 职场文书
七年级写作指导之游记作文
2019/10/07 职场文书
详解Python 3.10 中的新功能和变化
2021/04/28 Python
css height属性中的calc方法详解
2021/06/03 HTML / CSS
MySQL8.0.18配置多主一从
2021/06/21 MySQL
漫画《尖帽子的魔法工坊》宣布动画化
2022/04/06 日漫
golang定时器
2022/04/14 Golang