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 相关文章推荐
让iframe子窗体取父窗体地址栏参数(querystring)
Oct 13 Javascript
JavaScrip单线程引擎工作原理分析
Sep 04 Javascript
JavaScript高级程序设计 扩展--关于动态原型
Nov 09 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
Nov 01 Javascript
jQuery修改class属性和CSS样式整理
Jan 30 Javascript
JavaScript实现数组随机排序的方法
Jun 26 Javascript
2016年最热门的15 款代码语法高亮工具,美化你的代码
Jan 06 Javascript
js取小数点后两位四种方法
Jan 18 Javascript
微信小程序的mpvue框架快速上手指南
May 15 Javascript
浅谈JavaScript节流和防抖函数
Aug 25 Javascript
vue全局使用axios的操作
Sep 08 Javascript
html5中sharedWorker实现多页面通信的示例代码
May 07 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
PHP数组排序之sort、asort与ksort用法实例
2014/09/08 PHP
PHP改进计算字符串相似度的函数similar_text()、levenshtein()
2014/10/27 PHP
PHP通过串口实现发送短信
2015/07/08 PHP
prototype Element学习笔记(篇二)
2008/10/26 Javascript
jQuery的实现原理的模拟代码 -4 重要的扩展函数 extend
2010/08/03 Javascript
理解Javascript_01_理解内存分配原理分析
2010/10/11 Javascript
基于jQuery实现的当离开页面时出现提示的实现代码
2011/06/27 Javascript
JavaScript四种调用模式和this示例介绍
2014/01/02 Javascript
javascript中attribute和property的区别详解
2014/06/05 Javascript
JavaScript实现生成GUID(全局统一标识符)
2014/09/05 Javascript
基于javascript实现右下角浮动广告效果
2016/01/08 Javascript
基于JavaScript实现鼠标向下滑动加载div的代码
2016/08/31 Javascript
浅谈jquery选择器 :first与:first-child的区别
2016/11/20 Javascript
JS声明式函数与赋值式函数实例分析
2016/12/13 Javascript
bootstrap table实例详解
2017/01/06 Javascript
js学习总结_选项卡封装(实例讲解)
2017/07/13 Javascript
微信小程序 循环及嵌套循环的使用总结
2017/09/26 Javascript
利用JS判断客户端类型你应该知道的四种方法
2017/12/22 Javascript
iview中Select 选择器多选校验方法
2018/03/15 Javascript
对vue 键盘回车事件的实例讲解
2018/08/25 Javascript
NodeJs入门教程之定时器和队列
2019/03/08 NodeJs
Vue3新特性之在Composition API中使用CSS Modules
2020/07/13 Javascript
[03:06]3分钟带你回顾DOTA2完美盛典&完美大师赛
2017/12/06 DOTA
Python使用pylab库实现画线功能的方法详解
2017/06/08 Python
Python矩阵常见运算操作实例总结
2017/09/29 Python
解决python3捕获cx_oracle抛出的异常错误问题
2018/10/18 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
Django密码存储策略分析
2020/01/09 Python
Python读取yaml文件的详细教程
2020/07/21 Python
英国50岁以上人群的交友网站:Ourtime
2018/03/28 全球购物
linux面试题参考答案(4)
2013/01/28 面试题
营业员个人总结的自我评价
2013/10/25 职场文书
工业自动化毕业生自荐信范文
2014/01/04 职场文书
数控专业自荐书范文
2014/03/16 职场文书
Elasticsearch 索引操作和增删改查
2022/04/19 Python
nginx访问报403错误的几种情况详解
2022/07/23 Servers