檢視原始碼 zlib (erts v15.2)
zlib 壓縮介面。
此模組提供 zlib 函式庫的 API (www.zlib.net)。它用於壓縮和解壓縮資料。資料格式由 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
,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
tuple。詳細資訊請參閱 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
設定的屬性。
從指定未壓縮的位元組序列初始化解壓縮字典。
此函數必須作為對 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 串流。
-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
,Pid
必須是本機處理程序。
使用 zlib 標頭和檢查和解壓縮資料。
解壓縮不含 zlib 標頭和檢查和的資料。
壓縮不含 zlib 標頭和檢查和的資料。