IO.js ZLIB
稳定度: 2 - 稳定
要获取这个模块,你可以通过:
var zlib = require('zlib');
它提供了Gzip/Gunzip
,Deflate/Inflate
和DeflateRaw/InflateRaw
类的绑定。每个类都有相同的选项,并且都是可读/可写流。
例子
可以通过将一个fs.ReadStream
的数据导入一个zlib
流,然后导入一个fs.WriteStream
,来压缩或解压缩一个文件。
var gzip = zlib.createGzip();
var fs = require('fs');
var inp = fs.createReadStream('input.txt');
var out = fs.createWriteStream('input.txt.gz');
inp.pipe(gzip).pipe(out);
通过使用便捷方法,可以在一个步骤里完成压缩或解压缩数据。
var input = '.................................';
zlib.deflate(input, function(err, buffer) {
if (!err) {
console.log(buffer.toString('base64'));
}
});
var buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, function(err, buffer) {
if (!err) {
console.log(buffer.toString());
}
});
如果要在HTTP客户端或服务器上使用这个模块,在请求时需要带上accept-encoding
头,在响应时需要带上content-encoding
头。
注意,这些例子都只是非常简单的展示了一些基本的概念。zlib
编码的开销是非常昂贵的,并且结果需要被缓存。更多关于速度/内存/压缩的权衡,请参阅下文的内存使用调优
。
// client request example
var zlib = require('zlib');
var http = require('http');
var fs = require('fs');
var request = http.get({ host: 'izs.me',
path: '/',
port: 80,
headers: { 'accept-encoding': 'gzip,deflate' } });
request.on('response', function(response) {
var output = fs.createWriteStream('izs.me_index.html');
switch (response.headers['content-encoding']) {
// or, just use zlib.createUnzip() to handle both cases
case 'gzip':
response.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
response.pipe(zlib.createInflate()).pipe(output);
break;
default:
response.pipe(output);
break;
}
});
// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
var zlib = require('zlib');
var http = require('http');
var fs = require('fs');
http.createServer(function(request, response) {
var raw = fs.createReadStream('index.html');
var acceptEncoding = request.headers['accept-encoding'];
if (!acceptEncoding) {
acceptEncoding = '';
}
// Note: this is not a conformant accept-encoding parser.
// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
if (acceptEncoding.match(/\bdeflate\b/)) {
response.writeHead(200, { 'content-encoding': 'deflate' });
raw.pipe(zlib.createDeflate()).pipe(response);
} else if (acceptEncoding.match(/\bgzip\b/)) {
response.writeHead(200, { 'content-encoding': 'gzip' });
raw.pipe(zlib.createGzip()).pipe(response);
} else {
response.writeHead(200, {});
raw.pipe(response);
}
}).listen(1337);
zlib.createGzip([options])
根据一个options
,返回一个新的Gzip
对象。
zlib.createGunzip([options])
根据一个options
,返回一个新的Gunzip
对象。
zlib.createDeflate([options])
根据一个options
,返回一个新的Deflate
对象。
zlib.createInflate([options])
根据一个options
,返回一个新的Inflate
对象。
zlib.createDeflateRaw([options])
根据一个options
,返回一个新的DeflateRaw
对象。
zlib.createInflateRaw([options])
根据一个options
,返回一个新的InflateRaw
对象。
zlib.createUnzip([options])
根据一个options
,返回一个新的Unzip
对象。
Class: zlib.Zlib
这个类未被zlib
模块暴露。它之所以会出现在这里,是因为它是compressor/decompressor
类的基类。
zlib.flush([kind], callback)
kind
默认为zlib.Z_FULL_FLUSH
。
冲刷等待中的数据。不要轻率地调用这个方法,过早的冲刷会给压缩算法带来消极影响。
zlib.params(level, strategy, callback)
动态地更新压缩等级和压缩策略。只适用于deflate
算法。
zlib.reset()
将compressor/decompressor
重置为默认值。只使用于inflate
和deflate
算法。
Class: zlib.Gzip
使用gzip
压缩数据。
Class: zlib.Gunzip
解压一个gzip
流。
Class: zlib.Deflate
使用deflate
压缩数据。
Class: zlib.Inflate
解压一个deflate
流。
Class: zlib.DeflateRaw
使用deflate
压缩数据,不添加zlib
头。
Class: zlib.InflateRaw
解压一个原始deflate
流。
Class: zlib.Unzip
通过自动探测头信息,解压Gzip
或Deflate
压缩流。
便捷方法
所有的方法接受一个字符串或一个buffer
作为第一个参数,并且第二个参数是一个可选的 zlib
类的配置,并且会以callback(error, result)
的形式执行提供的回调函数。
每一个方法都有一个同步版本,除去回调函数,它们接受相同的参数。
zlib.deflate(buf[, options], callback)
zlib.deflateSync(buf[, options])
使用Deflate
压缩一个字符串。
zlib.deflateRaw(buf[, options], callback)
zlib.deflateRawSync(buf[, options])
使用DeflateRaw
压缩一个字符串。
zlib.gzip(buf[, options], callback)
zlib.gzipSync(buf[, options])
使用Gzip
压缩一个字符串。
zlib.gunzip(buf[, options], callback)
zlib.gunzipSync(buf[, options])
使用Gunzip
压缩一个字符串。
zlib.inflate(buf[, options], callback)
zlib.inflateSync(buf[, options])
使用Inflate
压缩一个字符串。
zlib.inflateRaw(buf[, options], callback)
zlib.inflateRawSync(buf[, options])
使用InflateRaw
压缩一个字符串。
zlib.unzip(buf[, options], callback)
zlib.unzipSync(buf[, options])
使用Unzip
压缩一个字符串。
Options
每一个类都接受一个options
对象。所有的options
对象都是可选的。
注意一些选项只与压缩相关,会被解压缩类忽略:
- flush (默认:
zlib.Z_NO_FLUSH
) - chunkSize (默认:
16*1024
) - windowBits
- level (仅用于压缩)
- memLevel (仅用于压缩)
- strategy (仅用于压缩)
- dictionary (仅用于
deflate/inflate
,默认为空目录)
参阅http://zlib.net/manual.html#Advanced
中deflateInit2
和inflateInit2
的描述来获取更多信息。
内存使用调优
来自zlib/zconf.h
,将其修改为io.js
的用法:
默认的内存要求(字节)为:
(1 << (windowBits+2)) + (1 << (memLevel+9))
换言之:windowBits=15
的128K 加上 menLevel = 8
(默认值)的128K 加上其他小对象的一些字节。
例子,如果你想要将默认内存需求从256K减少至128K,将选项设置为:
{ windowBits: 14, memLevel: 7 }
当然,它会降低压缩等级(没有免费的午餐)。
inflate
的内存需求(字节)为:
1 << windowBits
换言之:windowBits=15
(默认值)的32K加上其他小对象的一些字节。
这是内部输出缓冲外的chunkSize
大小,默认为16K。
zlib
压缩的速度动态得受设置的压缩等级的影响。高的等级会带来更好地压缩效果,但是花费的时间更长。低的等级会带来更少的压缩效果,但是更快。
通常,更高的内存使用选项意味着io.js
会调用zlib
更少次数,因为在一次单独的写操作中它可以处理更多的数据。所以,这是影响速度和内存占用的另一个因素。
常量
所有在zlib.h
中定义的常量,都也被定义在了require('zlib')
中。大多数操作中,你都将不会用到它们。它们出现在这里只是为了让你对它们的存在不套感到惊讶。该章节几乎完全来自zlib
文件。更多详情请参阅http://zlib.net/manual.html#Constants
。
允许的冲刷值:
zlib.Z_NO_FLUSH
zlib.Z_PARTIAL_FLUSH
zlib.Z_SYNC_FLUSH
zlib.Z_FULL_FLUSH
zlib.Z_FINISH
zlib.Z_BLOCK
zlib.Z_TREES
compression/decompression
函数的返回码。负值代表错误,正值代表特殊但是正常的事件:
zlib.Z_OK
zlib.Z_STREAM_END
zlib.Z_NEED_DICT
zlib.Z_ERRNO
zlib.Z_STREAM_ERROR
zlib.Z_DATA_ERROR
zlib.Z_MEM_ERROR
zlib.Z_BUF_ERROR
zlib.Z_VERSION_ERROR
压缩等级:
zlib.Z_NO_COMPRESSION
zlib.Z_BEST_SPEED
zlib.Z_BEST_COMPRESSION
zlib.Z_DEFAULT_COMPRESSION
压缩策略:
zlib.Z_FILTERED
zlib.Z_HUFFMAN_ONLY
zlib.Z_RLE
zlib.Z_FIXED
zlib.Z_DEFAULT_STRATEGY
data_type
域的可能值:
zlib.Z_BINARY
zlib.Z_TEXT
zlib.Z_ASCII
zlib.Z_UNKNOWN
deflate
压缩方法(当前版本只支持这一个):
zlib.Z_DEFLATED
用于初始化zalloc
,zfree
,opaque
:
zlib.Z_NULL
更多建议: