查看源代码 zlib (erts v15.2)

zlib 压缩接口。

此模块为 zlib 库 (www.zlib.net) 提供 API。它用于压缩和解压缩数据。数据格式由 RFC 1950RFC 1951RFC 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

摘要

类型

zlib 流,请参阅 open/0

通常在 -15..-8 | 8..15 范围内。

函数

关闭 Z 引用的流。

使用 zlib 标头和校验和压缩数据。

尽可能压缩数据,并在输入缓冲区为空时停止。

结束 deflate 会话并清除所有使用的数据。

zlib:deflateInit(Z, default) 相同。

初始化用于压缩的 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 引用的流。

-spec compress(Data) -> Compressed when Data :: iodata(), Compressed :: binary().

使用 zlib 标头和校验和压缩数据。

-spec deflate(Z, Data) -> Compressed when Z :: zstream(), Data :: iodata(), Compressed :: iolist().

deflate(Z, Data, none) 相同。

链接到此函数

deflate(Z, Data, Flush)

查看源代码
-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/1deflateEnd/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) 相同。

-spec deflateInit(Z, Level) -> ok when Z :: zstream(), Level :: zlevel().

初始化用于压缩的 zlib 流。

Level 决定要使用的压缩级别

  • default 在速度和压缩之间提供默认的折衷方案
  • none (0) 不压缩
  • best_speed (1) 提供最佳速度
  • best_compression (9) 提供最佳压缩
链接到此函数

deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy)

查看源代码
-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 编码,减少字符串匹配;它介于 defaulthuffman_only 之间。rle 的设计几乎与 huffman_only 一样快,但对于 PNG 图像数据提供了更好的压缩。

    Strategy 仅影响压缩率,而不影响压缩输出的正确性,即使未正确设置也是如此。

链接到此函数

deflateParams(Z, Level, Strategy)

查看源代码
-spec deflateParams(Z, Level, Strategy) -> ok
                       when Z :: zstream(), Level :: zlevel(), Strategy :: zstrategy().

动态更新压缩级别和压缩策略。

LevelStrategy 的解释与 deflateInit/6 中的相同。这可用于在压缩和输入数据的直接复制之间切换,或者切换到需要不同策略的不同类型的输入数据。如果压缩级别发生更改,则到目前为止可用的输入将使用旧级别压缩(并且可以刷新);新级别仅在下次调用 deflate/3 时生效。

在调用 deflateParams 之前,必须将流状态设置为调用 deflate/3 的状态,因为当前可用的输入可能必须压缩并刷新。

-spec deflateReset(Z) -> ok when Z :: zstream().

等效于 deflateEnd/1,后跟 deflateInit/1,2,6,但不释放和重新分配所有内部压缩状态。

该流保留相同的压缩级别和任何其他属性。

链接到此函数

deflateSetDictionary(Z, Dictionary)

查看源代码
-spec deflateSetDictionary(Z, Dictionary) -> Adler32
                              when Z :: zstream(), Dictionary :: iodata(), Adler32 :: non_neg_integer().

从指定的字节序列初始化压缩字典,而不生成任何压缩输出。

此函数必须在 deflateInit/1,2,6deflateReset/1 之后立即调用,在任何调用 deflate/3 之前调用。

压缩器和解压缩器必须使用相同的字典(请参阅 inflateSetDictionary/2)。

返回字典的 Adler 校验和。

-spec gunzip(Data) -> Decompressed when Data :: iodata(), Decompressed :: binary().

使用 gz 标头和校验和解压缩数据。

-spec gzip(Data) -> Compressed when Data :: iodata(), Compressed :: binary().

使用 gz 标头和校验和压缩数据。

-spec inflate(Z, Data) -> Decompressed when Z :: zstream(), Data :: iodata(), Decompressed :: iolist().

等效于 inflate(Z, Data, [])

链接到此函数

inflate(Z, Data, Options)

查看源代码 (自 OTP 20.1 起)
-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 异常。

链接到此函数

inflateGetDictionary(Z)

查看源代码 (自 OTP 20.0 起)
-spec inflateGetDictionary(Z) -> Dictionary when Z :: zstream(), Dictionary :: binary().

返回流当前使用的解压缩字典。

此函数必须在 inflateInit/1,2inflateEnd 之间调用。

仅当 ERTS 使用 zlib >= 1.2.8 编译时才支持。

-spec inflateInit(Z) -> ok when Z :: zstream().

初始化用于解压缩的 zlib 流。

链接到此函数

inflateInit(Z, WindowBits)

查看源代码
-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 设置的属性。

链接到此函数

inflateSetDictionary(Z, Dictionary)

查看源代码
-spec inflateSetDictionary(Z, Dictionary) -> ok when Z :: zstream(), Dictionary :: iodata().

从指定的未压缩字节序列初始化解压缩字典。

必须调用此函数以响应返回 {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 流。

链接到此函数

safeInflate(Z, Data)

查看源代码 (自 OTP 20.1 起)
-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).
链接到此函数

set_controlling_process(Z, Pid)

查看源代码 (自 OTP 20.1.3 起)
-spec set_controlling_process(Z, Pid) -> ok when Z :: zstream(), Pid :: pid().

Z 的控制进程更改为 Pid,后者必须是本地进程。

-spec uncompress(Data) -> Decompressed when Data :: iodata(), Decompressed :: binary().

使用 zlib 标头和校验和解压缩数据。

-spec unzip(Data) -> Decompressed when Data :: iodata(), Decompressed :: binary().

解压缩没有 zlib 标头和校验和的数据。

-spec zip(Data) -> Compressed when Data :: iodata(), Compressed :: binary().

压缩没有 zlib 标头和校验和的数据。