檢視原始碼 zlib (erts v15.2)

zlib 壓縮介面。

此模組提供 zlib 函式庫的 API (www.zlib.net)。它用於壓縮和解壓縮資料。資料格式由 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 的控制處理程序變更為 PidPid 必須是本機處理程序。

使用 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 tuple。詳細資訊請參閱 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().

從指定未壓縮的位元組序列初始化解壓縮字典。

此函數必須作為對 inflate 操作(例如,safeInflate/2)的回應而被呼叫,該操作返回 {need_dictionary,Adler,Output},或者在已棄用函數的情況下,拋出 {'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 的控制處理程序變更為 PidPid 必須是本機處理程序。

-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 標頭和檢查和的資料。