查看源代码 zlib (erts v15.2)
zlib 压缩接口。
此模块为 zlib 库 (www.zlib.net) 提供 API。它用于压缩和解压缩数据。数据格式由 RFC 1950、RFC 1951 和 RFC 1952 描述。
典型的(压缩)用法如下:
Z = zlib:open(),
ok = zlib:deflateInit(Z,default),
Compress = fun(end_of_data, _Cont) -> [];
(Data, Cont) ->
[zlib:deflate(Z, Data)|Cont(Read(),Cont)]
end,
Compressed = Compress(Read(),Compress),
Last = zlib:deflate(Z, [], finish),
ok = zlib:deflateEnd(Z),
zlib:close(Z),
list_to_binary([Compressed|Last])
在所有函数中,可以抛出错误,{'EXIT',{Reason,Backtrace}}
,其中 Reason
描述错误。
典型的 Reason
:
badarg
- 参数错误。not_initialized
- 流尚未初始化,例如,如果在调用inflate/2
之前未调用inflateInit/1
。not_on_controlling_process
- 该流被不控制它的进程使用。如果需要将流传输到不同的进程,请使用set_controlling_process/2
。data_error
- 数据包含错误。stream_error
- 流状态不一致。{need_dictionary,Adler32}
- 请参阅inflate/2
。
摘要
类型
通常在 -15..-8 | 8..15
范围内。
函数
关闭 Z
引用的流。
使用 zlib 标头和校验和压缩数据。
尽可能压缩数据,并在输入缓冲区为空时停止。
结束 deflate 会话并清除所有使用的数据。
与 zlib:deflateInit(Z, default)
相同。
初始化用于压缩的 zlib 流。
启动用于压缩的 zlib 流。
动态更新压缩级别和压缩策略。
等效于 deflateEnd/1
,后跟 deflateInit/1,2,6
,但不释放和重新分配所有内部压缩状态。
从指定的字节序列初始化压缩字典,而不生成任何压缩输出。
使用 gz 标头和校验和解压缩数据。
使用 gz 标头和校验和压缩数据。
尽可能解压缩数据。它可能会引入一些输出延迟(读取输入而不产生任何输出)。
结束 inflate 会话并清除所有使用的数据。
返回流当前使用的解压缩字典。
初始化用于解压缩的 zlib 流。
在 zlib 流上初始化解压缩会话。
等效于 inflateEnd/1
,后跟 inflateInit/1
,但不释放和重新分配所有内部解压缩状态。该流将保留可能已由 inflateInit/1,2
设置的属性。
从指定的未压缩字节序列初始化解压缩字典。
打开 zlib 流。
类似于 inflate/2
,但一旦它扩展超过一个小的实现定义的阈值,就会返回。当解压缩不受信任的输入时,这很有用,这些输入可能已被恶意构造为扩展到系统内存耗尽为止。
将 Z
的控制进程更改为 Pid
,后者必须是本地进程。
使用 zlib 标头和校验和解压缩数据。
解压缩没有 zlib 标头和校验和的数据。
压缩没有 zlib 标头和校验和的数据。
类型
-type zflush() :: none | sync | full | finish.
-type zlevel() :: none | default | best_compression | best_speed | 0..9.
-type zmemlevel() :: 1..9.
-type zmethod() :: deflated.
-type zstrategy() :: default | filtered | huffman_only | rle.
-type zstream() :: reference().
zlib 流,请参阅 open/0
。
-type zwindowbits() :: -15..-8 | 8..47.
通常在 -15..-8 | 8..15
范围内。
函数
-spec close(Z) -> ok when Z :: zstream().
关闭 Z
引用的流。
使用 zlib 标头和校验和压缩数据。
与 deflate(Z, Data, none)
相同。
-spec deflate(Z, Data, Flush) -> Compressed when Z :: zstream(), Data :: iodata(), Flush :: zflush(), Compressed :: iolist().
尽可能压缩数据,并在输入缓冲区为空时停止。
它可以引入一些输出延迟(读取输入而不产生任何输出),除非强制刷新。
如果 Flush
设置为 sync
,则所有挂起的输出都会刷新到输出缓冲区,并且输出在字节边界上对齐,以便解压缩器可以获得到目前为止可用的所有输入数据。刷新可能会降低某些压缩算法的压缩率;因此,仅在必要时使用它。
如果 Flush
设置为 full
,则所有输出都与 sync
一样刷新,并且压缩状态会重置,以便在以前的压缩数据已损坏或需要随机访问时,可以从此时重新启动解压缩。过于频繁地使用 full
会严重降低压缩率。
如果 Flush
设置为 finish
,则会处理挂起的输入,刷新挂起的输出,并且 deflate/3
返回。之后,流上唯一可能的操作是 deflateReset/1
或 deflateEnd/1
。
如果所有压缩都要在一个步骤中完成,则可以在 deflateInit
之后立即将 Flush
设置为 finish
。
示例
zlib:deflateInit(Z),
B1 = zlib:deflate(Z,Data),
B2 = zlib:deflate(Z,<< >>,finish),
zlib:deflateEnd(Z),
list_to_binary([B1,B2])
-spec deflateEnd(Z) -> ok when Z :: zstream().
结束 deflate 会话并清除所有使用的数据。
请注意,如果上次调用 deflate/3
时未将 Flush
设置为 finish
,则此函数会抛出 data_error
异常。
-spec deflateInit(Z) -> ok when Z :: zstream().
与 zlib:deflateInit(Z, default)
相同。
初始化用于压缩的 zlib 流。
Level
决定要使用的压缩级别
default
在速度和压缩之间提供默认的折衷方案none
(0) 不压缩best_speed
(1) 提供最佳速度best_compression
(9) 提供最佳压缩
-spec deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> ok when Z :: zstream(), Level :: zlevel(), Method :: zmethod(), WindowBits :: zwindowbits(), MemLevel :: zmemlevel(), Strategy :: zstrategy().
启动用于压缩的 zlib 流。
Level
- 要使用的压缩级别default
在速度和压缩之间提供默认的折衷方案none
(0) 不压缩best_speed
(1) 提供最佳速度best_compression
(9) 提供最佳压缩
Method
- 要使用的压缩方法,当前唯一支持的方法是deflated
。WindowBits
- 窗口大小(历史缓冲区的大小)的以 2 为底的对数。它应在 8 到 15 的范围内。较大的值会提高压缩率,但会占用更多内存。如果使用deflateInit/2
,则默认为 15。负WindowBits
值会从流中抑制 zlib 标头(和校验和)。请注意,zlib 源代码仅将其视为未记录的功能。警告
由于底层 zlib 库中存在已知错误,
WindowBits
值 8 和 -8 不会按预期工作。在 1.2.9 之前的 zlib 版本中,值 8 和 -8 会自动更改为 9 和 -9。从 zlib 版本 1.2.9 开始,值 -8 被拒绝导致zlib:deflateInit/6
失败(8 仍更改为 9)。似乎未来的 zlib 版本也可能修复此错误并开始按原样接受 8 和 -8。结论:除非您知道您的 zlib 版本支持它们,否则请避免使用值 8 和 -8。
MemLevel
- 指定为内部压缩状态分配多少内存:MemLevel
=1 使用最少内存,但速度慢且会降低压缩率;MemLevel
=9 使用最大内存以获得最佳速度。默认为 8。Strategy
- 调整压缩算法。使用以下值default
用于普通数据filtered
用于过滤器(或预测器)生成的数据huffman_only
强制仅使用 Huffman 编码(无字符串匹配)rle
将匹配距离限制为一个(游程编码)
过滤后的数据主要由具有一定随机分布的小值组成。在这种情况下,压缩算法会进行调整以更好地压缩它们。
filtered
的效果是强制进行更多的 Huffman 编码,减少字符串匹配;它介于default
和huffman_only
之间。rle
的设计几乎与huffman_only
一样快,但对于 PNG 图像数据提供了更好的压缩。Strategy
仅影响压缩率,而不影响压缩输出的正确性,即使未正确设置也是如此。
-spec deflateParams(Z, Level, Strategy) -> ok when Z :: zstream(), Level :: zlevel(), Strategy :: zstrategy().
动态更新压缩级别和压缩策略。
Level
和 Strategy
的解释与 deflateInit/6
中的相同。这可用于在压缩和输入数据的直接复制之间切换,或者切换到需要不同策略的不同类型的输入数据。如果压缩级别发生更改,则到目前为止可用的输入将使用旧级别压缩(并且可以刷新);新级别仅在下次调用 deflate/3
时生效。
在调用 deflateParams
之前,必须将流状态设置为调用 deflate/3
的状态,因为当前可用的输入可能必须压缩并刷新。
-spec deflateReset(Z) -> ok when Z :: zstream().
等效于 deflateEnd/1
,后跟 deflateInit/1,2,6
,但不释放和重新分配所有内部压缩状态。
该流保留相同的压缩级别和任何其他属性。
-spec deflateSetDictionary(Z, Dictionary) -> Adler32 when Z :: zstream(), Dictionary :: iodata(), Adler32 :: non_neg_integer().
从指定的字节序列初始化压缩字典,而不生成任何压缩输出。
此函数必须在 deflateInit/1,2,6
或 deflateReset/1
之后立即调用,在任何调用 deflate/3
之前调用。
压缩器和解压缩器必须使用相同的字典(请参阅 inflateSetDictionary/2
)。
返回字典的 Adler 校验和。
使用 gz 标头和校验和解压缩数据。
使用 gz 标头和校验和压缩数据。
-spec inflate(Z, Data, Options) -> Decompressed when Z :: zstream(), Data :: iodata(), Options :: [{exception_on_need_dict, boolean()}], Decompressed :: iolist() | {need_dictionary, Adler32 :: non_neg_integer(), Output :: iolist()}.
尽可能解压缩数据。它可能会引入一些输出延迟(读取输入而不产生任何输出)。
目前唯一可用的选项是 {exception_on_need_dict,boolean()}
,它控制当解压缩需要预设字典时,该函数是否应抛出异常。如果设置为 false,则会返回一个 need_dictionary
元组。有关详细信息,请参阅 inflateSetDictionary/2
。
警告
为了向后兼容,此选项默认为
true
,但我们计划在未来的版本中删除此异常行为。需要手动处理字典的新代码应始终指定{exception_on_need_dict,false}
。
-spec inflateEnd(Z) -> ok when Z :: zstream().
结束 inflate 会话并清除所有使用的数据。
请注意,如果未找到流的结尾(表示并非所有数据都已解压缩),此函数将抛出 data_error
异常。
返回流当前使用的解压缩字典。
此函数必须在 inflateInit/1,2
和 inflateEnd
之间调用。
仅当 ERTS 使用 zlib >= 1.2.8 编译时才支持。
-spec inflateInit(Z) -> ok when Z :: zstream().
初始化用于解压缩的 zlib 流。
-spec inflateInit(Z, WindowBits) -> ok when Z :: zstream(), WindowBits :: zwindowbits().
在 zlib 流上初始化解压缩会话。
WindowBits
是最大窗口大小(历史缓冲区的大小)的以 2 为底的对数。它必须在 8 到 15 的范围内。如果使用 inflateInit/1
,则默认为 15。
如果指定一个具有较大窗口大小的压缩流作为输入,则 inflate/2
会抛出 data_error
异常。
负的 WindowBits
值使 zlib 忽略流中的 zlib 标头(和校验和)。请注意,zlib 源代码仅将其提及为未文档化的功能。
-spec inflateReset(Z) -> ok when Z :: zstream().
等效于 inflateEnd/1
,后跟 inflateInit/1
,但不释放和重新分配所有内部解压缩状态。该流将保留可能已由 inflateInit/1,2
设置的属性。
从指定的未压缩字节序列初始化解压缩字典。
必须调用此函数以响应返回 {need_dictionary,Adler,Output}
的 inflate 操作(例如 safeInflate/2
),或者在已弃用的函数的情况下,抛出 {'EXIT',{{need_dictionary,Adler},_StackTrace}}
异常。
压缩器选择的字典可以从 inflate 函数调用返回或抛出的 Adler 值确定。压缩器和解压缩器必须使用相同的字典(请参阅 deflateSetDictionary/2
)。
设置字典后,应在没有新输入的情况下重试 inflate 操作。
示例
deprecated_unpack(Z, Compressed, Dict) ->
case catch zlib:inflate(Z, Compressed) of
{'EXIT',{{need_dictionary,_DictID},_}} ->
ok = zlib:inflateSetDictionary(Z, Dict),
Uncompressed = zlib:inflate(Z, []);
Uncompressed ->
Uncompressed
end.
new_unpack(Z, Compressed, Dict) ->
case zlib:inflate(Z, Compressed, [{exception_on_need_dict, false}]) of
{need_dictionary, _DictId, Output} ->
ok = zlib:inflateSetDictionary(Z, Dict),
[Output | zlib:inflate(Z, [])];
Uncompressed ->
Uncompressed
end.
-spec open() -> zstream().
打开 zlib 流。
-spec safeInflate(Z, Data) -> Result when Z :: zstream(), Data :: iodata(), Result :: {continue, Output :: iolist()} | {finished, Output :: iolist()} | {need_dictionary, Adler32 :: non_neg_integer(), Output :: iolist()}.
类似于 inflate/2
,但一旦它扩展超过一个小的实现定义的阈值,就会返回。当解压缩不受信任的输入时,这很有用,这些输入可能已被恶意构造为扩展到系统内存耗尽为止。
此函数返回 {continue | finished, Output}
,其中 Output 是此调用中解压缩的数据。如果需要,可以在每次调用时排队新的输入,并且一旦所有排队的数据都被解压缩,该函数将返回 {finished, Output}
。
此函数可能会引入一些输出延迟(读取输入而不产生任何输出)。
如果需要预设字典进行进一步解压缩,此函数将返回一个 need_dictionary
元组。有关详细信息,请参阅 inflateSetDictionary/2
)。
示例
walk(Compressed, Handler) ->
Z = zlib:open(),
zlib:inflateInit(Z),
loop(Z, Handler, zlib:safeInflate(Z, Compressed)),
zlib:inflateEnd(Z),
zlib:close(Z).
loop(Z, Handler, {continue, Output}) ->
Handler(Output),
loop(Z, Handler, zlib:safeInflate(Z, []));
loop(Z, Handler, {finished, Output}) ->
Handler(Output).
将 Z
的控制进程更改为 Pid
,后者必须是本地进程。
使用 zlib 标头和校验和解压缩数据。
解压缩没有 zlib 标头和校验和的数据。
压缩没有 zlib 标头和校验和的数据。