复制

描述

将文件或资源集合复制到新的文件或目录。默认情况下,仅当源文件比目标文件更新或目标文件不存在时才复制文件 - 请参阅 granularity 属性以了解 Ant 对“更新”的理解。但是,您可以使用 overwrite 属性显式覆盖文件。

资源集合 用于选择要复制的一组文件。要使用资源集合,必须设置 todir 属性。注意,某些资源(例如 文件 资源)返回绝对路径作为名称,在不使用嵌套映射器(或 flatten 属性)的情况下使用它们的结果可能与您的预期不符。

注意:如果您在复制操作中使用过滤器,则应将复制限制为文本文件。二进制文件将因复制操作而损坏。这适用于过滤器是通过 filter 任务隐式定义还是作为 filtersets 显式提供给复制操作的。参见 编码说明

参数

属性 描述 必需
文件 要复制的文件。 是,除非使用嵌套资源集合元素
preservelastmodified 使复制文件的最后修改时间与原始源文件相同。 否;默认为 false
tofile 要复制到的文件。在 Apache Ant 1.8.2 之前,tofile 属性仅支持 文件资源 进行复制。 使用 file 属性,可以使用 tofiletodir
使用嵌套资源集合元素,如果包含的资源数量大于 1,或者如果仅在 <fileset> 中指定了 dir 属性,或者如果还指定了 file 属性,则仅允许使用 todir
todir 要复制到的目录。
overwrite 即使目标文件更新,也覆盖现有文件。 否;默认为 false
force 覆盖只读目标文件。自 Ant 1.8.2 起 否;默认为 false
filtering 指示在复制过程中是否应使用 全局构建文件过滤器 进行令牌过滤。注意:即使未指定此属性,或其值为 falsenooff,嵌套的 <filterset> 元素也将始终使用。 否;默认为 false
flatten 忽略源文件的目录结构,并将所有文件复制到 todir 属性指定的目录中。请注意,您可以通过使用 flatten 映射器 来实现相同的效果。 否;默认为 false
includeEmptyDirs 复制 FileSet(s) 中包含的任何空目录。 否;默认为 true
failonerror 如果为 false,则记录警告消息,但不停止构建,当要复制的文件不存在或其中一个嵌套 fileset 指向不存在的目录或复制时发生错误。 否;默认为 true
quiet 如果为 truefailonerrorfalse,则当要复制的文件不存在或其中一个嵌套 fileset 指向不存在的目录或复制时发生错误时,不记录警告消息。自 Ant 1.8.3 起 否;默认为 false
verbose 记录正在复制的文件。 否;默认为 false
encoding 在过滤复制文件时假设的编码。自 Ant 1.5 起 否;默认为默认 JVM 字符编码
outputencoding 写入文件时使用的编码。自 Ant 1.6 起 否;默认为 encoding(如果已设置)或默认 JVM 字符编码(否则)
enablemultiplemappings 如果为 true,则任务将处理给定源路径的所有映射。如果为 false,则任务将仅处理第一个文件或目录。此属性仅在存在 mapper 子元素时才相关。自 Ant 1.6 起 否;默认为 false
granularity 在确定文件已过期之前要给予的毫秒级宽限期。这是必需的,因为并非所有文件系统都支持将最后修改时间跟踪到毫秒级。如果源文件和目标文件位于时钟不同步的单独机器上,这也很有用。自 Ant 1.6.2 起 否;默认值为 1 秒,或在 DOS 系统上为 2 秒

作为嵌套元素指定的参数

任何基于文件系统的资源集合

资源集合 用于选择要复制的一组文件。要使用资源集合,必须设置 todir 属性。

在 Ant 1.7 之前,仅支持 <fileset> 作为嵌套元素。

mapper

您可以通过使用嵌套的 mapper 元素来定义文件名转换。<copy> 使用的默认映射器是 identity 映射器

自 Ant 1.6.3 起,可以使用文件名映射器类型来代替映射器元素。

请注意,传递给映射器的源名称取决于您使用的资源集合。如果您使用 <fileset> 或任何其他提供基本目录的集合,则传递给映射器的名称将是相对于基本目录的相对文件名。在任何其他情况下,都将使用源的绝对文件名。

filterset

FilterSet 用于替换复制文件的令牌。要使用 FilterSet,请使用嵌套的 <filterset> 元素。

可以使用多个 filterset。

filterchain

Copy 任务支持嵌套的 FilterChain

如果在同一个 <copy> 任务中使用 <filterset><filterchain> 元素,则首先处理所有 <filterchain> 元素,然后处理 <filterset> 元素。

示例

复制单个文件

<copy file="myfile.txt" tofile="mycopy.txt"/>

将单个文件复制到目录

<copy file="myfile.txt" todir="../some/other/dir"/>

将目录复制到另一个目录

<copy todir="../new/dir">
  <fileset dir="src_dir"/>
</copy>

将一组文件复制到目录

<copy todir="../dest/dir">
  <fileset dir="src_dir">
    <exclude name="**/*.java"/>
  </fileset>
</copy>

<copy todir="../dest/dir">
  <fileset dir="src_dir" excludes="**/*.java"/>
</copy>

将一组文件复制到目录,在文件名中动态追加 .bak

<copy todir="../backup/dir">
  <fileset dir="src_dir"/>
  <globmapper from="*" to="*.bak"/>
</copy>

将一组文件复制到目录,将所有文件中的 @TITLE@ 替换为 Foo Bar

<copy todir="../backup/dir">
  <fileset dir="src_dir"/>
  <filterset>
    <filter token="TITLE" value="Foo Bar"/>
  </filterset>
</copy>

将当前 CLASSPATH 设置中的所有项目收集到目标目录中,扁平化目录结构。

<copy todir="dest" flatten="true">
  <path>
    <pathelement path="${java.class.path}"/>
  </path>
</copy>

将一些资源复制到给定目录。

<copy todir="dest" flatten="true">
  <resources>
    <file file="src_dir/file1.txt"/>
    <url url="https://ant.apache.org/index.html"/>
  </resources>
</copy>

如果上面的示例没有使用 flatten 属性,<file> 资源将返回其完整路径作为源名称和目标名称,并且根本不会被复制。通常,最好将显式映射器与使用绝对路径作为其名称的资源一起使用。

将两个最新的资源复制到目标目录。

<copy todir="dest" flatten="true">
  <first count="2">
    <sort>
      <date xmlns="antlib:org.apache.tools.ant.types.resources.comparators"/>
      <resources>
        <file file="src_dir/file1.txt"/>
        <file file="src_dir/file2.txt"/>
        <file file="src_dir/file3.txt"/>
        <url url="https://ant.apache.org/index.html"/>
      </resources>
    </sort>
  </first>
</copy>

前面示例后的段落也适用于此示例。

Unix 说明:复制文件时不会保留文件权限;它们最终会获得默认的 UMASK 权限。这是由于当前 Java 运行时缺乏查询或设置文件权限的任何方法造成的。如果您需要保留权限的复制功能,请改用 <exec executable="cp" ... >

Windows 说明:如果您将文件复制到该文件已存在但大小写不同的目录,则复制的文件将采用原始文件的大小写。解决方法是在复制文件之前 删除 目标目录中的文件。

重要编码说明:过滤后的二进制文件损坏的原因是过滤涉及使用 Reader 类读取文件。这具有指定文件编码方式的编码。有许多不同类型的编码 - UTF-8、UTF-16、Cp1252、ISO-8859-1、US-ASCII 和(很多)其他编码。在 Windows 上,默认字符编码为 Cp1252,在 Unix 上通常为 UTF-8。对于这两种编码,都存在非法的字节序列(UTF-8 中比 Cp1252 中更多)。

Reader 类如何处理这些非法序列取决于字符解码器的实现。当前的 Sun Java 实现是将它们映射到合法字符。以前的 Sun Java(1.3 及更低版本)抛出 MalformedInputException。IBM Java 1.4 也抛出此异常。正是字符的映射导致了损坏。

在 Unix 上,默认情况下通常为 UTF-8,这是一个问题,因为很容易编辑文件以包含来自 ISO-8859-1 的非 US-ASCII 字符,例如丹麦语 œ 字符。当 Ant 复制(带过滤)它时,字符会被转换为问号(或类似的东西)。

Ant 几乎无能为力。它无法确定哪些文件是二进制文件 - 韩国语的 UTF-8 版本将包含许多最高位设置为 1 的字节。它没有从当前的 Sun Java 实现中获得有关非法字符序列的信息。

一个仅包含 US-ASCII 的过滤技巧是使用 ISO-8859-1 编码。这似乎不包含非法字符序列,并且较低的 7 位是 US-ASCII。另一个技巧是将 LANG 环境变量从类似 us.utf8 的内容更改为 us