查看源码 zip (stdlib v6.2)

用于读取和创建 'zip' 归档文件的实用工具。

此模块将文件归档和提取到 zip 归档文件。zip 格式由 “ZIP Appnote.txt” 文件指定,该文件可在 PKWARE 网站 www.pkware.com 上找到。

zip 模块支持最高 6.1 版本的 zip 归档文件。但是,不支持密码保护。

按照惯例,zip 文件的名称应以 .zip 结尾。要遵守惯例,请将 .zip 添加到文件名。

  • 要创建 zip 归档文件,请使用函数 zip/2zip/3。它们也可以作为 create/2,3 使用,以类似于 erl_tar 模块。
  • 要从 zip 归档文件中提取文件,请使用函数 unzip/1unzip/2。它们也可以作为 extract/1,2 使用,以类似于 erl_tar 模块。
  • 要对 zip 归档文件中的所有文件折叠一个函数,请使用函数 foldl/3
  • 要返回 zip 归档文件中文件列表,请使用函数 list_dir/1list_dir/2。它们也可以作为 table/1,2 使用,以类似于 erl_tar 模块。
  • 要在 Erlang shell 中打印文件列表,请使用函数 t/1tt/1
  • 有时,需要打开一个 zip 归档文件,并从中逐个文件解压缩文件,而无需重新打开归档文件。这可以通过函数 zip_open/1,2zip_get/1,2zip_list_dir/1zip_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 归档文件中提取所有文件。

创建一个 zip 归档文件,其中包含 FileList 中指定的文件。

关闭先前使用 zip_open/1,2 打开的 zip 归档文件。所有资源都将关闭,并且关闭后不得使用句柄。

从打开的归档文件中提取一个或所有文件。

从打开的归档文件中提取一个 crc32 校验和。

返回打开的 zip 归档文件的文件列表。第一个返回的元素是 zip 归档注释。

打开一个 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 中描述。

链接到此类型

extension()

查看源码 (未导出)
-type extension() :: string().

文件扩展名,例如 “.txt”。

链接到此类型

extension_spec()

查看源码 (未导出)
-type extension_spec() ::
          all |
          [Extension :: extension()] |
          {add, [Extension :: extension()]} |
          {del, [Extension :: extension()]}.
链接到此类型

extra()

查看源码 (未导出)
-type extra() :: [extended_timestamp | uid_gid].

可以使用的可能的额外扩展。

  • extended_timestamp - 启用 0x5455 “扩展时间戳” zip 扩展,该扩展为归档文件中的每个文件的访问和修改时间嵌入 POSIX 时间戳。这使得时间戳采用 UTC 而不是本地时间,并且还将时间分辨率从 2 秒提高到 1 秒。
  • uid_gid - 启用 0x7875 “UNIX 第 3 代” zip 扩展,该扩展将每个文件的 UID 和 GID 嵌入到归档文件中。
-type filename() :: file:filename().

zip 文件的名称。

-opaque handle()

zip_open/2 返回。

链接到此类型

zip_comment()

查看源码 (未导出)
-type zip_comment() :: #zip_comment{comment :: string()}.

记录 zip_comment 仅包含 zip 归档文件的归档注释。

链接到此类型

zip_file()

查看源码 (未导出)
-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 中所示。如果使用 calendar:datetime/0 表示,则 mtimeatimectime 预计采用 本地时间,如果使用整数表示,则采用 OS 系统时间

  • comment - zip 归档文件中文件的注释

  • offset - zip 归档文件中的文件偏移量(内部使用)

  • comp_size - 压缩文件的大小(未压缩文件的大小在 info 中找到)

erl_tar 兼容性函数

链接到此函数

create(Name, FileList)

查看源码
-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)

链接到此函数

create(Name, FileList, Options)

查看源码
-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()}.

等效于 zip(Name, FileList, Options)

-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)

链接到此函数

extract(Archive, Options)

查看源码
-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, [])

链接到此函数

table(Archive, Options)

查看源码
-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.

等效于 list_dir(Archive, Options)

函数

链接到此函数

foldl(Fun, Acc0, Archive)

查看源码 (自 OTP R14B 起)
-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 中调用 GetInfoGetBin。如果在 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, [])

链接到此函数

list_dir(Archive, Options)

查看源码
-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 添加到模式列表会覆盖默认值,并打开 zip 文件而不使用选项 raw

  • skip_directories - 默认情况下,zip 存档中的空目录会被列出。如果设置了选项 skip_directories,则不再列出空目录。

  • {extra, Extras} - 要考虑的 zip “额外” 功能。支持的“额外”功能是“扩展时间戳”和“UID 和 GID”处理。默认情况下,列出文件时仅启用“扩展时间戳”。有关更多详细信息,请参阅 extra/0

-spec t(Archive) -> ok when Archive :: file:name() | binary() | ZipHandle, ZipHandle :: handle().

将 zip 归档文件 Archive 中的所有文件名打印到 Erlang shell。(类似于 tar t。)

-spec tt(Archive) -> ok when Archive :: file:name() | binary() | ZipHandle, ZipHandle :: handle().

将 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, [])

链接到此函数

unzip(Archive, Options)

查看源码
-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, [])

链接到此函数

zip(Name, FileList, Options)

查看源码
-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()}.

创建一个 zip 归档文件,其中包含 FileList 中指定的文件。

FileList 是一个文件列表,其中路径相对于当前目录,并使用此路径存储在存档中。执行文件系统操作以读取文件元数据,并且在启用压缩时,可以流式传输文件内容,而无需将整个文件加载到内存中。也可以将文件指定为二进制文件,以直接从数据创建存档。在这种情况下,不会执行元数据或文件系统读取操作。

文件使用 DEFLATE 压缩进行压缩,如“Appnote.txt”文件中所述。但是,如果文件已经被压缩,则将不进行压缩而存储。 zip/2zip/3 会检查文件扩展名,以确定是否应将文件存储而不进行压缩。具有以下扩展名的文件不会被压缩:.Z.zip.zoo.arc.lzh.arj

可以通过使用选项 {compress, What}{uncompress, What} 来覆盖默认行为,并控制要压缩的文件类型。还可以使用多个 compressuncompress 选项。

要触发文件压缩,其扩展名必须与 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]} - 从解压缩扩展名列表中删除这些扩展名。

链接到此函数

zip_close(ZipHandle)

查看源码
-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

链接到此函数

zip_get(FileName, ZipHandle)

查看源码
-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 指定的选项。

链接到此函数

zip_get_crc32(FileName, ZipHandle)

查看源代码 (自 OTP 26.0 起)
-spec zip_get_crc32(FileName, ZipHandle) -> {ok, CRC} | {error, Reason}
                       when
                           FileName :: file:name(),
                           ZipHandle :: handle(),
                           CRC :: non_neg_integer(),
                           Reason :: term().

从打开的归档文件中提取一个 crc32 校验和。

链接到此函数

zip_list_dir(ZipHandle)

查看源码
-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

链接到此函数

zip_open(Archive, Options)

查看源码
-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 会被关闭。