檢視原始碼 zip (stdlib v6.2)
用於讀取和建立 'zip' 壓縮檔的工具。
此模組可將檔案壓縮至 zip 壓縮檔或從 zip 壓縮檔中解壓縮。zip 格式由 PKWARE 網站上的 "ZIP Appnote.txt" 檔案指定 www.pkware.com。
zip 模組支援最高至 6.1 版的 zip 壓縮檔。但是,不支援密碼保護。
依慣例,zip 檔案的名稱應以 .zip
結尾。為了遵守慣例,請將 .zip
新增至檔名。
- 若要建立 zip 壓縮檔,請使用函式
zip/2
或zip/3
。它們也以create/2,3
的形式提供,以類似於erl_tar
模組。 - 若要從 zip 壓縮檔中解壓縮檔案,請使用函式
unzip/1
或unzip/2
。它們也以extract/1,2
的形式提供,以類似於erl_tar
模組。 - 若要對 zip 壓縮檔中的所有檔案摺疊函式,請使用函式
foldl/3
。 - 若要傳回 zip 壓縮檔中檔案的清單,請使用函式
list_dir/1
或list_dir/2
。它們也以table/1,2
的形式提供,以類似於erl_tar
模組。 - 若要將檔案清單列印至 Erlang shell,請使用函式
t/1
或tt/1
。 - 有時,最好開啟 zip 壓縮檔,並逐個檔案從其中解壓縮檔案,而不必重新開啟壓縮檔。這可以使用函式
zip_open/1,2
、zip_get/1,2
、zip_list_dir/1
和zip_close/1
來完成。 - 支援 ZIP 擴充功能 0x5355「擴充時間戳記」和 0x7875「UID+GID 處理」。依預設,建立壓縮檔時會啟用這兩個擴充功能,但在解壓縮時只會啟用「擴充時間戳記」。使用
extra/0
選項來變更這些擴充功能的使用方式。
限制
- 不支援受密碼保護和加密的壓縮檔。
- 僅支援 DEFLATE(zlib 壓縮)和 STORE(未壓縮資料)zip 方法。
- 建立 zip 壓縮檔時,不支援個別檔案的註解。支援整個 zip 壓縮檔的 zip 壓縮檔註解。
- 不支援變更 zip 壓縮檔。若要從壓縮檔新增或移除檔案,必須重新建立整個壓縮檔。
摘要
類型
這些選項在 create/3
中說明。
副檔名,例如 ".txt"。
可使用的額外擴充功能。
zip 檔案的名稱。
由 zip_open/2
傳回。
記錄 zip_comment
只包含 zip 壓縮檔的壓縮檔註解。
記錄 zip_file
包含下列欄位
函式
在 Archive
中的後續檔案上呼叫 Fun(FileInArchive, GetInfo, GetBin, AccIn)
,從 AccIn == Acc0
開始。
擷取 zip 壓縮檔 Archive
中的所有檔名。
將 zip 壓縮檔 Archive
中的所有檔名列印至 Erlang shell。(類似於 tar t
。)
將 zip 壓縮檔 Archive
中的檔名和所有檔案的相關資訊列印至 Erlang shell。(類似於 tar tv
。)
從 zip 壓縮檔解壓縮所有檔案。
建立包含 FileList
中指定的檔案的 zip 壓縮檔。
關閉先前以 zip_open/1,2
開啟的 zip 壓縮檔。所有資源都會關閉,且在關閉後不得使用控制代碼。
與 zip_get/2
相等。
從開啟的壓縮檔解壓縮一個或所有檔案。
從開啟的壓縮檔解壓縮一個 crc32 檢查碼。
傳回開啟的 zip 壓縮檔的檔案清單。第一個傳回的元素是 zip 壓縮檔註解。
與 zip_open/2
相等。
開啟 zip 壓縮檔,並讀取和儲存其目錄。這表示稍後從壓縮檔讀取檔案的速度,比使用 unzip/1,2
一次解壓縮一個檔案快。
類型
-type create_option() :: memory | cooked | verbose | {comment, Comment :: string()} | {cwd, CWD :: file:filename()} | {compress, What :: extension_spec()} | {uncompress, What :: extension_spec()} | {extra, extra()}.
這些選項在 create/3
中說明。
-type extension() :: string().
副檔名,例如 ".txt"。
-type extra() :: [extended_timestamp | uid_gid].
可使用的額外擴充功能。
extended_timestamp
- 啟用 0x5455「擴充時間戳記」zip 擴充功能,該功能會針對壓縮檔中的每個檔案嵌入 POSIX 時間戳記,以用於存取和修改時間。這會使時間戳記成為 UTC 時間,而不是當地時間,並將時間解析度從 2 秒提高到 1 秒。uid_gid
- 啟用 0x7875「UNIX 第三代」zip 擴充功能,該功能會將每個檔案的 UID 和 GID 嵌入壓縮檔中。
-type filename() :: file:filename().
zip 檔案的名稱。
-opaque handle()
由 zip_open/2
傳回。
-type zip_comment() :: #zip_comment{comment :: string()}.
記錄 zip_comment
只包含 zip 壓縮檔的壓縮檔註解。
-type zip_file() :: #zip_file{name :: string(), info :: file:file_info(), comment :: string(), offset :: non_neg_integer(), comp_size :: non_neg_integer()}.
記錄 zip_file
包含下列欄位
name
- 檔名info
- 檔案資訊,如 Kernel 中的file:read_file_info/1
中所示。mtime
、atime
和ctime
預期為使用calendar:datetime/0
表示時,為當地時間
;或以整數表示時,為OS 系統時間。comment
- zip 壓縮檔中檔案的註解offset
- 檔案在 zip 壓縮檔中的偏移量(內部使用)comp_size
- 壓縮檔案的大小(未壓縮檔案的大小會在info
中找到)
erl_tar 相容性函式
-spec create(Name, FileList) -> RetValue when Name :: file:name(), FileList :: [FileSpec], FileSpec :: file:name() | {file:name(), binary()} | {file:name(), binary(), file:file_info()}, RetValue :: {ok, FileName :: filename()} | {ok, {FileName :: filename(), binary()}} | {error, Reason :: term()}.
與 zip(Name, FileList)
相等。
-spec create(Name, FileList, Options) -> RetValue when Name :: file:name(), FileList :: [FileSpec], FileSpec :: file:name() | {file:name(), binary()} | {file:name(), binary(), file:file_info()}, Options :: [Option], Option :: create_option(), RetValue :: {ok, FileName :: filename()} | {ok, {FileName :: filename(), binary()}} | {error, Reason :: term()}.
-spec extract(Archive) -> RetValue when Archive :: file:name() | binary(), RetValue :: {ok, FileList} | {ok, FileBinList} | {error, Reason :: term()} | {error, {Name :: file:name(), Reason :: term()}}, FileList :: [file:name()], FileBinList :: [{file:name(), binary()}].
與 unzip(Archive)
相等。
-spec extract(Archive, Options) -> RetValue when Archive :: file:name() | binary(), Options :: [Option], Option :: {file_list, FileList} | keep_old_files | verbose | memory | {file_filter, FileFilter} | {cwd, CWD}, FileList :: [file:name()], FileBinList :: [{file:name(), binary()}], FileFilter :: fun((ZipFile) -> boolean()), CWD :: file:filename(), ZipFile :: zip_file(), RetValue :: {ok, FileList} | {ok, FileBinList} | {error, Reason :: term()} | {error, {Name :: file:name(), Reason :: term()}}.
與 unzip(Archive, Options)
相等。
-spec table(Archive) -> RetValue when Archive :: file:name() | binary(), RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()}, CommentAndFiles :: [zip_comment() | zip_file()].
與 list_dir(Archive, [])
相等。
-spec table(Archive, Options) -> RetValue when Archive :: file:name() | binary(), RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()}, CommentAndFiles :: [zip_comment() | zip_file()], Options :: [Option], Option :: cooked.
函式
-spec foldl(Fun, Acc0, Archive) -> {ok, Acc1} | {error, Reason} when Fun :: fun((FileInArchive, GetInfo, GetBin, AccIn) -> AccOut), FileInArchive :: file:name(), GetInfo :: fun(() -> file:file_info()), GetBin :: fun(() -> binary()), Acc0 :: term(), Acc1 :: term(), AccIn :: term(), AccOut :: term(), Archive :: file:name() | {file:name(), binary()}, Reason :: term().
在 Archive
中的後續檔案上呼叫 Fun(FileInArchive, GetInfo, GetBin, AccIn)
,從 AccIn == Acc0
開始。
FileInArchive
是檔案在壓縮檔中具有的名稱。
GetInfo
是傳回檔案相關資訊的函式。
GetBin
會傳回檔案內容。
必須在 Fun
中呼叫 GetInfo
和 GetBin
。如果在 Fun
的內容之外呼叫它們,則其行為未定義。
Fun
必須傳回新的累加器,該累加器會傳遞給下一個呼叫。foldl/3
會傳回最終的累加器值。如果壓縮檔為空,則會傳回 Acc0
。沒有必要迭代壓縮檔中的所有檔案。可以透過擲回例外狀況以受控制的方式過早結束迭代。
範例
> Name = "dummy.zip".
"dummy.zip"
> {ok, {Name, Bin}} = zip:create(Name, [{"foo", <<"FOO">>}, {"bar", <<"BAR">>}], [memory]).
{ok,{"dummy.zip",
<<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
0,0,3,0,0,...>>}}
> {ok, FileSpec} = zip:foldl(fun(N, I, B, Acc) -> [{N, B(), I()} | Acc] end, [], {Name, Bin}).
{ok,[{"bar",<<"BAR">>,
{file_info,3,regular,read_write,
{{2010,3,1},{19,2,10}},
{{2010,3,1},{19,2,10}},
{{2010,3,1},{19,2,10}},
54,1,0,0,0,0,0}},
{"foo",<<"FOO">>,
{file_info,3,regular,read_write,
{{2010,3,1},{19,2,10}},
{{2010,3,1},{19,2,10}},
{{2010,3,1},{19,2,10}},
54,1,0,0,0,0,0}}]}
> {ok, {Name, Bin}} = zip:create(Name, lists:reverse(FileSpec), [memory]).
{ok,{"dummy.zip",
<<80,75,3,4,20,0,0,0,0,0,74,152,97,60,171,39,212,26,3,0,
0,0,3,0,0,...>>}}
> catch zip:foldl(fun("foo", _, B, _) -> throw(B()); (_,_,_,Acc) -> Acc end, [], {Name, Bin}).
<<"FOO">>
-spec list_dir(Archive) -> RetValue when Archive :: file:name() | binary(), RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()}, CommentAndFiles :: [zip_comment() | zip_file()].
與 list_dir(Archive, [])
相等。
-spec list_dir(Archive, Options) -> RetValue when Archive :: file:name() | binary(), RetValue :: {ok, CommentAndFiles} | {error, Reason :: term()}, CommentAndFiles :: [zip_comment() | zip_file()], Options :: [Option], Option :: cooked | {extra, extra()}.
擷取 zip 壓縮檔 Archive
中的所有檔名。
結果值為元組 {ok, List}
,其中 List
包含 zip 壓縮檔註解作為第一個元素。
有一個選項可用
cooked
- 預設情況下,此函式會以raw
模式開啟 zip 檔案,這種模式速度較快,但不允許使用遠端 (Erlang) 檔案伺服器。在模式列表中加入cooked
會覆寫預設值,並在不使用raw
選項的情況下開啟 zip 檔案。skip_directories
- 預設情況下,會列出 zip 封存檔中的空目錄。設定skip_directories
選項後,將不再列出空目錄。{extra, Extras}
- 要考慮的 zip "額外" 功能。支援的 "額外" 功能為 "擴展時間戳記" 和 "UID 與 GID" 處理。預設情況下,在列出檔案時僅啟用 "擴展時間戳記"。如需更多詳細資訊,請參閱extra/0
。
將 zip 壓縮檔 Archive
中的所有檔名列印至 Erlang shell。(類似於 tar t
。)
將 zip 壓縮檔 Archive
中的檔名和所有檔案的相關資訊列印至 Erlang shell。(類似於 tar tv
。)
-spec unzip(Archive) -> RetValue when Archive :: file:name() | binary(), RetValue :: {ok, FileList} | {ok, FileBinList} | {error, Reason :: term()} | {error, {Name :: file:name(), Reason :: term()}}, FileList :: [file:name()], FileBinList :: [{file:name(), binary()}].
與 unzip(Archive, [])
相等。
-spec unzip(Archive, Options) -> RetValue when Archive :: file:name() | binary(), Options :: [Option], Option :: {file_list, FileList} | cooked | keep_old_files | verbose | memory | {file_filter, FileFilter} | {cwd, CWD} | {extra, extra()}, FileList :: [file:name()], FileBinList :: [{file:name(), binary()}], FileFilter :: fun((ZipFile) -> boolean()), CWD :: file:filename(), ZipFile :: zip_file(), RetValue :: {ok, FileList} | {ok, FileBinList} | {error, Reason :: term()} | {error, {Name :: file:name(), Reason :: term()}}.
從 zip 壓縮檔解壓縮所有檔案。
如果將引數 Archive
指定為 binary/0
,則會假設該二進位內容為 zip 封存檔,否則會被視為檔名。
選項
{file_list, FileList}
- 預設情況下,會從 zip 封存檔中解壓縮所有檔案。使用{file_list, FileList}
選項時,函式unzip/2
只會解壓縮名稱包含在FileList
中的檔案。必須指定完整路徑,包括 zip 封存檔內所有子目錄的名稱。cooked
- 預設情況下,此函式會以raw
模式開啟 zip 檔案,這種模式速度較快,但不允許使用遠端 (Erlang) 檔案伺服器。在模式列表中加入cooked
會覆寫預設值,並在不使用raw
選項的情況下開啟 zip 檔案。這同樣適用於解壓縮的檔案。keep_old_files
- 預設情況下,所有與 zip 封存檔中檔案同名的檔案都會被覆寫。設定keep_old_files
選項後,函式unzip/2
不會覆寫現有檔案。請注意,即使指定了memory
選項 (表示不會覆寫任何檔案),現有檔案也會從結果中排除。skip_directories
- 預設情況下,會解壓縮 zip 封存檔中的空目錄。設定skip_directories
選項後,將不再建立空目錄。{extra, Extras}
- 要考慮的 zip "額外" 功能。支援的 "額外" 功能為 "擴展時間戳記" 和 "UID 與 GID" 處理。預設情況下,在解壓縮時僅啟用 "擴展時間戳記"。如需更多詳細資訊,請參閱extra/0
。verbose
- 列印每個解壓縮檔案的資訊訊息。memory
- 結果不會解壓縮到目前目錄,而是以元組清單{Filename, Binary}
的形式提供,其中Binary
是一個二進位檔案,包含 zip 封存檔中檔案Filename
的解壓縮資料。{cwd, CWD}
- 使用指定的目錄作為目前目錄。當從 zip 封存檔中解壓縮檔案時,會將此目錄附加到檔名之前。(作用類似 Kernel 中的file:set_cwd/1
,但不變更全域cwd
屬性。)
-spec zip(Name, FileList) -> RetValue when Name :: file:name(), FileList :: [FileSpec], FileSpec :: file:name() | {file:name(), binary()} | {file:name(), binary(), file:file_info()}, RetValue :: {ok, FileName :: file:name()} | {ok, {FileName :: file:name(), binary()}} | {error, Reason :: term()}.
與 zip(Name, FileList, [])
相等。
-spec zip(Name, FileList, Options) -> RetValue when Name :: file:name(), FileList :: [FileSpec], FileSpec :: file:name() | {file:name(), binary()} | {file:name(), binary(), file:file_info()}, Options :: [Option], Option :: create_option(), RetValue :: {ok, FileName :: file:name()} | {ok, {FileName :: file:name(), binary()}} | {error, Reason :: term()}.
建立包含 FileList
中指定的檔案的 zip 壓縮檔。
FileList
是一個檔案清單,其路徑相對於目前目錄,並以該路徑儲存在封存檔中。執行檔案系統操作以讀取檔案中繼資料,並且在啟用壓縮時,會串流檔案內容,而不會將整個檔案載入記憶體。檔案也可以指定為二進位檔案,以直接從資料建立封存檔。在這種情況下,不會執行任何中繼資料或檔案系統讀取。
檔案會使用「Appnote.txt」檔案中描述的 DEFLATE 壓縮進行壓縮。但是,如果檔案已經過壓縮,則會不經壓縮直接儲存。 zip/2
和 zip/3
會檢查檔案副檔名,以判斷是否要不經壓縮儲存檔案。具有以下副檔名的檔案不會壓縮: .Z
、.zip
、.zoo
、.arc
、.lzh
、.arj
。
可以覆寫預設行為,並透過使用選項 {compress, What}
和 {uncompress, What}
來控制要壓縮的檔案類型。也可以使用多個 compress
和 uncompress
選項。
若要觸發檔案壓縮,其副檔名必須符合 compress
條件,且不得符合 uncompress
條件。例如,如果將 compress
設定為 ["gif", "jpg"]
,並將 uncompress
設定為 ["jpg"]
,則只會壓縮副檔名為 "gif"
的檔案。
選項
cooked
- 預設情況下,此函式會以raw
模式開啟 zip 檔案,這種模式速度較快,但不允許使用遠端 (Erlang) 檔案伺服器。在模式列表中加入cooked
會覆寫預設值,並在不使用raw
選項的情況下開啟 zip 檔案。這同樣適用於新增的檔案。verbose
- 列印有關每個新增檔案的資訊訊息。memory
- 輸出不會寫入檔案,而是以元組{FileName, binary()}
的形式輸出。二進位檔案是具有標頭的完整 zip 封存檔,可以使用例如unzip/2
來解壓縮。{comment, Comment}
- 在 zip 封存檔中加入註解。{cwd, CWD}
- 使用指定的目錄作為目前工作目錄 (cwd
)。當加入檔案時,會將此目錄附加到檔名之前,但不會在 zip 封存檔中附加 (作用類似 Kernel 中的file:set_cwd/1
,但不變更全域cwd
屬性)。{extra, Extras}
- 要考慮的 zip "額外" 功能。支援的 "額外" 功能為 "擴展時間戳記" 和 "UID 與 GID" 處理。預設情況下,會同時啟用這兩種 "額外" 功能。如需更多詳細資訊,請參閱extra/0
。{compress, What}
- 控制要壓縮的檔案類型。預設值為all
。允許的What
值如下all
- 壓縮所有檔案 (只要它們通過uncompress
條件)。[Extension]
- 僅壓縮具有這些確切副檔名的檔案。{add,[Extension]}
- 將這些副檔名新增至壓縮副檔名清單。{del,[Extension]}
- 從壓縮副檔名清單中刪除這些副檔名。
{uncompress, What}
- 控制要解壓縮的檔案類型。預設值為[".Z", ".zip", ".zoo", ".arc", ".lzh", ".arj"]
。允許的What
值如下all
- 不壓縮任何檔案。[Extension]
- 解壓縮具有這些副檔名的檔案。{add,[Extension]}
- 將這些副檔名新增至解壓縮副檔名清單。{del,[Extension]}
- 從解壓縮副檔名清單中刪除這些副檔名。
-spec zip_close(ZipHandle) -> ok | {error, einval} when ZipHandle :: handle().
關閉先前以 zip_open/1,2
開啟的 zip 壓縮檔。所有資源都會關閉,且在關閉後不得使用控制代碼。
-spec zip_get(ZipHandle) -> {ok, [Result]} | {error, Reason} when ZipHandle :: handle(), Result :: file:name() | {file:name(), binary()}, Reason :: term().
與 zip_get/2
相等。
-spec zip_get(FileName, ZipHandle) -> {ok, Result} | {error, Reason} when FileName :: file:name(), ZipHandle :: handle(), Result :: file:name() | {file:name(), binary()}, Reason :: term().
從開啟的壓縮檔解壓縮一個或所有檔案。
根據開啟封存檔時指定給函式 zip_open/1,2
的選項,將檔案解壓縮到記憶體或檔案。
-spec zip_get_crc32(FileName, ZipHandle) -> {ok, CRC} | {error, Reason} when FileName :: file:name(), ZipHandle :: handle(), CRC :: non_neg_integer(), Reason :: term().
從開啟的壓縮檔解壓縮一個 crc32 檢查碼。
-spec zip_list_dir(ZipHandle) -> {ok, Result} | {error, Reason} when Result :: [zip_comment() | zip_file()], ZipHandle :: handle(), Reason :: term().
傳回開啟的 zip 壓縮檔的檔案清單。第一個傳回的元素是 zip 壓縮檔註解。
-spec zip_open(Archive) -> {ok, ZipHandle} | {error, Reason} when Archive :: file:name() | binary(), ZipHandle :: handle(), Reason :: term().
與 zip_open/2
相等。
-spec zip_open(Archive, Options) -> {ok, ZipHandle} | {error, Reason} when Archive :: file:name() | binary(), ZipHandle :: handle(), Options :: [Option], Option :: cooked | memory | {cwd, CWD :: file:filename()} | {extra, extra()}, Reason :: term().
開啟 zip 壓縮檔,並讀取和儲存其目錄。這表示稍後從壓縮檔讀取檔案的速度,比使用 unzip/1,2
一次解壓縮一個檔案快。
這些選項與 unzip/2
中的選項相同。
必須使用 zip_close/1
關閉封存檔。
如果最初開啟封存檔的處理程序終止,則會關閉 ZipHandle
。