查看源码 erl_tar (stdlib v6.2)

用于读取和写入 tar 归档的 Unix 'tar' 工具。

此模块将文件归档和提取到 tar 文件中。此模块支持读取大多数常见的 tar 格式,即 v7、STAR、USTAR 和 PAX,以及 GNU tar 对 USTAR 格式的一些扩展(最值得注意的是稀疏文件)。它生成 USTAR 格式的 tar 归档,除非要归档的文件由于 USTAR 的限制(例如 Unicode 元数据、文件名长度等)而需要 PAX 格式。因此,erl_tar 支持由大多数现代 tar 工具生成的 tar 归档,并生成应同样具有可移植性的 tarball。

按照惯例,tar 文件的名称应以 “.tar” 结尾。为了遵守惯例,请将 “.tar” 添加到名称中。

可以使用函数 create/2create/3 在一个操作中创建 tar 文件。

或者,为了更好地控制,可以使用函数 open/2add/3,4close/1

要从 tar 文件中提取所有文件,请使用函数 extract/1。要仅提取某些文件或能够指定更多选项,请使用函数 extract/2

要返回 tar 文件中文件列表,请使用函数 table/1table/2。要将文件列表打印到 Erlang shell,请使用函数 t/1tt/1

要将上述函数返回的错误项转换为可读的消息,请使用函数 format_error/1

Unicode 支持

如果 file:native_name_encoding/0 返回 utf8,则在创建 tar 文件时,路径名将以 UTF-8 编码,并且在提取 tar 文件时,假定路径名以 UTF-8 编码。

如果 file:native_name_encoding/0 返回 latin1,则不会进行路径名的转换。

PAX 标头中存储的 Unicode 元数据将保留

其他存储介质

ftp 模块通常使用 file 模块访问磁盘上的 tar 文件。当出现其他需求时,您可以定义自己的底层 Erlang 函数来在存储介质上执行写入和读取操作;请使用函数 init/3

这方面的一个示例是 ssh_sftp:open_tar/3 中的 SFTP 支持。此函数使用 SFTP 通道打开远程计算机上的 tar 文件。

限制

  • 如果您必须与 USTAR tar 格式保持兼容,则必须确保存储的文件路径总共小于 255 字节,且最大文件名组件长度为 100 字节。USTAR 除了名称字段外,还使用标头字段(前缀),并将长于 100 字节的文件路径拆分为两个部分。这种拆分是在目录边界上进行的,并且以尽可能利用这两个字段中的可用空间的方式进行,但实际上,这通常意味着您用于路径的字节数少于 255 个。erl_tar 将自动将格式升级为 PAX 以处理更长的文件名,因此,这仅在您需要使用不支持 PAX 的 erl_tartar 的旧版本提取归档时才成为问题。在这种情况下,PAX 标头将作为常规文件提取,您将需要手动应用它们。
  • 与上述类似,如果您必须保持 USTAR 兼容,则还必须确保符号/硬链接的路径不超过 100 字节,否则将使用 PAX 标头。

摘要

函数

将文件添加到已通过 open/1 打开进行写入的 tar 文件。

关闭由 open/2 打开的 tar 文件。

创建 tar 文件并将名称在 FileList 中指定的文件归档到其中。这些文件可以从磁盘读取,也可以指定为二进制文件。

创建 tar 文件并将名称在 FileList 中指定的文件归档到其中。这些文件可以从磁盘读取,也可以指定为二进制文件。

从 tar 归档中提取所有文件。

从 tar 归档中提取文件。

将错误原因项转换为人类可读的错误消息字符串。

Fun 是定义在从较高 tar 处理函数(如 add/3add/4close/1)调用不同的存储操作函数时要执行的操作。

创建用于写入的 tar 文件(任何具有相同名称的现有文件都将被截断)。

将 tar 文件 Name 中所有文件的名称打印到 Erlang shell(类似于 “tar t”)。

检索 tar 文件 Name 中所有文件的名称。

将 tar 文件 Name 中所有文件的名称和信息打印到 Erlang shell(类似于 “tar tv”)。

类型

链接到此类型

add_opt()

查看源码 (未导出)
-type add_opt() ::
          dereference | verbose |
          {chunks, pos_integer()} |
          {atime, non_neg_integer()} |
          {mtime, non_neg_integer()} |
          {ctime, non_neg_integer()} |
          {uid, non_neg_integer()} |
          {gid, non_neg_integer()}.
链接到此类型

create_opt()

查看源码 (未导出)
-type create_opt() :: compressed | cooked | dereference | verbose.
链接到此类型

extract_opt()

查看源码 (未导出)
-type extract_opt() ::
          {cwd, string()} |
          {files, [name_in_archive()]} |
          compressed | cooked | memory | keep_old_files | verbose.
链接到此类型

file_op()

查看源码 (未导出)
-type file_op() ::
          fun((write | close | read2 | position,
               {user_data(), iodata()} |
               user_data() |
               {user_data(), non_neg_integer()} |
               {user_data(), non_neg_integer()}) ->
                  ok | eof | {ok, string() | binary()} | {ok, non_neg_integer()} | {error, term()}).
链接到此类型

filelist()

查看源码 (未导出)
-type filelist() :: [file:filename() | {name_in_archive(), file:filename_all()}].
-type gid() :: non_neg_integer().
链接到此类型

mode()

查看源码 (未导出)
-type mode() :: non_neg_integer().
链接到此类型

name_in_archive()

查看源码 (未导出)
-type name_in_archive() :: string().
链接到此类型

open_type()

查看源码 (未导出)
-type open_type() :: file:filename_all() | {binary, binary()} | {file, file:io_device()}.
-opaque tar_descriptor()
链接到此类型

tar_entry()

查看源码 (未导出)
-type tar_entry() ::
          {Name :: name_in_archive(),
           Type :: typeflag(),
           Size :: non_neg_integer(),
           MTime :: tar_time(),
           Mode :: mode(),
           Uid :: uid(),
           Gid :: gid()}.
链接到此类型

tar_time()

查看源码 (未导出)
-type tar_time() :: non_neg_integer().
链接到此类型

typeflag()

查看源码 (未导出)
-type typeflag() :: regular | link | symlink | char | block | directory | fifo | reserved | unknown.
-type uid() :: non_neg_integer().
链接到此类型

user_data()

查看源码 (未导出)
-type user_data() :: term().

函数

链接到此函数

add(TarDescriptor, Name, Options)

查看源码
-spec add(TarDescriptor, Name, Options) -> ok | {error, term()}
             when
                 TarDescriptor :: tar_descriptor(),
                 Name :: name_in_archive() | {name_in_archive(), file:filename_all()},
                 Options :: [add_opt()].

等效于 add/4

如果 Namename_in_archive/0,则调用 add(TarDescriptor, Name, Name, Options)

如果 Name 是一个二元组,则调用 add(TarDescriptor, NameInArchive, Name, Options)

链接到此函数

add(TarDescriptor, Filename, NameInArchive, Options)

查看源码
-spec add(TarDescriptor, Filename, NameInArchive, Options) -> ok | {error, term()}
             when
                 TarDescriptor :: tar_descriptor(),
                 Filename :: file:filename_all(),
                 NameInArchive :: name_in_archive(),
                 Options :: [add_opt()].

将文件添加到已通过 open/1 打开进行写入的 tar 文件。

NameInArchive 是该文件在 tar 文件中存储的名称。当从 tar 文件中提取该文件时,它将获得此名称。

选项

  • dereference - 默认情况下,符号链接在 tar 文件中存储为符号链接。要覆盖默认值并将符号链接指向的文件存储到 tar 文件中,请使用选项 dereference

  • verbose - 打印有关添加文件的信息性消息。

  • {chunks,ChunkSize} - 从文件中分部分读取数据。这适用于内存受限的计算机,例如,在远程计算机上通过 SFTP 构建 tar 文件,请参阅 ssh_sftp:open_tar/3

  • {atime,non_neg_integer()} - 设置上次读取文件的时间,以 POSIX 时间表示。另请参阅 file:read_file_info/1

  • {mtime,non_neg_integer()} - 设置上次写入文件的时间,以 POSIX 时间表示。另请参阅 file:read_file_info/1

  • {ctime,non_neg_integer()} - 设置文件创建的时间,以 POSIX 时间表示。另请参阅 file:read_file_info/1

  • {uid,non_neg_integer()} - 设置文件所有者。file:read_file_info/1

  • {gid,non_neg_integer()} - 设置文件所有者所属的组。file:read_file_info/1

链接到此函数

close(TarDescriptor)

查看源码
-spec close(TarDescriptor :: tar_descriptor()) -> ok | {error, term()}.

关闭由 open/2 打开的 tar 文件。

链接到此函数

create(Name, FileList)

查看源码
-spec create(file:filename_all(), filelist()) -> ok | {error, {string(), term()}}.

创建 tar 文件并将名称在 FileList 中指定的文件归档到其中。这些文件可以从磁盘读取,也可以指定为二进制文件。

链接到此函数

create(Name, FileList, Options)

查看源码
-spec create(file:filename_all(), filelist(), [create_opt()]) ->
                ok | {error, term()} | {error, {string(), term()}}.

创建 tar 文件并将名称在 FileList 中指定的文件归档到其中。这些文件可以从磁盘读取,也可以指定为二进制文件。

OptionList 中的选项按如下方式修改默认值

  • compressed - 整个 tar 文件被压缩,就像已通过 gzip 程序运行一样。为了遵守压缩 tar 文件应以 “.tar.gz” 或 “.tgz” 结尾的惯例,请添加适当的扩展名。

  • cooked - 默认情况下,函数 open/2raw 模式打开 tar 文件,这种模式速度更快,但不允许使用远程 (Erlang) 文件服务器。将 cooked 添加到模式列表会覆盖默认设置,并在不使用 raw 选项的情况下打开 tar 文件。

  • dereference - 默认情况下,符号链接在 tar 文件中存储为符号链接。要覆盖默认值并将符号链接指向的文件存储到 tar 文件中,请使用选项 dereference

  • verbose - 打印有关每个添加文件的信息消息。

-spec extract(Open :: open_type()) -> ok | {error, term()}.

从 tar 归档中提取所有文件。

如果参数 Name 被指定为 {binary,Binary},则假定二进制文件的内容是 tar 归档文件。

如果参数 Name 被指定为 {file,Fd},则假定 Fd 是从函数 file:open/2 返回的文件描述符。

否则,Name 应为文件名。

注意

在写入文件之前,tar 成员名称中的前导斜杠将被删除。也就是说,绝对路径将转换为相对路径。当以这种方式更改路径时,会向错误记录器写入一条信息消息。

警告

当使用 {file,Fd} 传递文件描述符时,compressedcooked 标志无效。假定文件已使用适当的标志打开。

-spec extract(Open :: open_type(), [extract_opt()]) ->
                 {ok, [{string(), binary()}]} | {error, term()} | ok.

从 tar 归档中提取文件。

如果参数 Name 被指定为 {binary,Binary},则假定二进制文件的内容是 tar 归档文件。

如果参数 Name 被指定为 {file,Fd},则假定 Fd 是从函数 file:open/2 返回的文件描述符。

否则,Name 应为文件名。

以下选项修改了提取的默认设置,如下所示

  • {cwd,Cwd} - 默认情况下,具有相对文件名的文件会提取到当前工作目录。使用此选项,文件将改为提取到目录 Cwd

  • {files,FileList} - 默认情况下,所有文件都会从 tar 文件中提取。使用此选项,仅提取名称包含在 FileList 中的文件。

  • compressed - 使用此选项,将在提取时解压缩文件。如果 tar 文件未压缩,则忽略此选项。

  • cooked - 默认情况下,函数 open/2raw 模式打开 tar 文件,这种模式速度更快,但不允许使用远程 (Erlang) 文件服务器。将 cooked 添加到模式列表会覆盖默认设置,并在不使用 raw 选项的情况下打开 tar 文件。

  • memory - 此选项不会提取到目录,而是将结果作为元组列表 {Filename, Binary} 给出,其中 Binary 是一个二进制文件,其中包含 tar 文件中名为 Filename 的文件的提取数据。

  • keep_old_files - 默认情况下,所有与 tar 文件中文件名相同的文件将被覆盖。使用此选项,现有文件不会被覆盖。

  • verbose - 为每个提取的文件打印一条信息消息。

警告

当使用 {file,Fd} 传递文件描述符时,compressedcooked 标志无效。假定文件已使用适当的标志打开。

-spec format_error(term()) -> string().

将错误原因项转换为人类可读的错误消息字符串。

链接到此函数

init/3

查看源代码 (自 OTP 17.4 起)
-spec init(UserData :: user_data(), write | read, file_op()) -> {ok, tar_descriptor()} | {error, badarg}.

Fun 是定义在从较高 tar 处理函数(如 add/3add/4close/1)调用不同的存储操作函数时要执行的操作。

当 tar 函数想要执行低级操作(例如将块写入文件)时,将调用 FunFun 的调用方式为 Fun(Op, {UserData,Parameters...}),其中 Op 是操作名称,UserData 是作为第一个参数传递给 init/1 的项,Parameters... 是 tar 函数添加的要传递给存储处理函数的数据。

参数 UserData 通常是打开低级结构(如文件描述符或 SFTP 通道 ID)的结果。不同的 Fun 子句对该项进行操作。

以下是 fun 子句参数列表

  • (write, {UserData,DataToWrite}) - 使用 UserData 写入项 DataToWrite

  • (close, UserData) - 关闭访问。

  • (read2, {UserData,Size}) - 使用 UserData 读取,但仅读取 Size 个字节。请注意,只有一个 arity-2 读取函数,而不是 arity-1 函数。

  • (position,{UserData,Position}) - 设置 UserData 的位置,如 file:position/2 中为文件定义的那样

示例

以下是使用 file 模块在文件上进行读取和写入的完整 Fun 参数

ExampleFun =
   fun(write, {Fd,Data}) ->  file:write(Fd, Data);
      (position, {Fd,Pos}) -> file:position(Fd, Pos);
      (read2, {Fd,Size}) -> file:read(Fd, Size);
      (close, Fd) -> file:close(Fd)
   end

此处,Fd 已指定给函数 init/3,如下所示

{ok,Fd} = file:open(Name, ...).
{ok,TarDesc} = erl_tar:init(Fd, [write], ExampleFun),

然后使用 TarDesc

erl_tar:add(TarDesc, SomeValueIwantToAdd, FileNameInTarFile),
...,
erl_tar:close(TarDesc)

erl_tar 核心想要执行操作(例如,写入一段 Data)时,它会调用 ExampleFun(write, {UserData,Data})

注意

此示例使用 file 模块操作不是必须直接使用的,因为这原则上是函数 open/2 所做的事情。

警告

TarDescriptor 项不是文件描述符。建议您不要依赖此项的具体内容,因为当此模块添加更多功能时,它可能会在未来的 Erlang/OTP 版本中更改。

-spec open(Open :: open_type(), [write | compressed | cooked]) ->
              {ok, tar_descriptor()} | {error, term()}.

创建用于写入的 tar 文件(任何具有相同名称的现有文件都将被截断)。

按照惯例,tar 文件的名称应以 “.tar” 结尾。为了遵守惯例,请将 “.tar” 添加到名称中。

除了 write 原子外,以下原子可以添加到 OpenModeList

  • compressed - 整个 tar 文件被压缩,就像已通过 gzip 程序运行一样。为了遵守压缩 tar 文件应以 “.tar.gz” 或 “.tgz” 结尾的惯例,请添加适当的扩展名。

  • cooked - 默认情况下,tar 文件以 raw 模式打开,这种模式速度更快,但不允许使用远程 (Erlang) 文件服务器。将 cooked 添加到模式列表会覆盖默认设置,并在不使用 raw 选项的情况下打开 tar 文件。

要一次向打开的 tar 文件中添加一个文件,请使用函数 add/3,4。添加完文件后,请使用函数 close/1 关闭 tar 文件。

警告

当使用 {file,Fd} 传递文件描述符时,compressedcooked 标志无效。文件必须已使用适当的标志打开。

警告

TarDescriptor 项不是文件描述符。建议您不要依赖此项的具体内容,因为当此模块添加更多功能时,它可能会在未来的 Erlang/OTP 版本中更改。

-spec t(file:filename()) -> ok | {error, term()}.

将 tar 文件 Name 中所有文件的名称打印到 Erlang shell(类似于 “tar t”)。

-spec table(Open :: open_type()) -> {ok, [name_in_archive()]} | {error, term()}.

等效于 table(Open, [])

-spec table(Open :: open_type(), [compressed | verbose | cooked]) ->
               {ok, [name_in_archive() | tar_entry()]} | {error, term()}.

检索 tar 文件 Name 中所有文件的名称。

-spec tt(open_type()) -> ok | {error, term()}.

将 tar 文件 Name 中所有文件的名称和信息打印到 Erlang shell(类似于 “tar tv”)。