将文件或资源集合复制到新的文件或目录。默认情况下,仅当源文件比目标文件更新或目标文件不存在时才复制文件 - 请参阅 granularity 属性以了解 Ant 对“更新”的理解。但是,您可以使用 overwrite
属性显式覆盖文件。
资源集合 用于选择要复制的一组文件。要使用资源集合,必须设置 todir 属性。注意,某些资源(例如 文件 资源)返回绝对路径作为名称,在不使用嵌套映射器(或 flatten 属性)的情况下使用它们的结果可能与您的预期不符。
注意:如果您在复制操作中使用过滤器,则应将复制限制为文本文件。二进制文件将因复制操作而损坏。这适用于过滤器是通过 filter 任务隐式定义还是作为 filtersets 显式提供给复制操作的。参见 编码说明。
属性 | 描述 | 必需 |
---|---|---|
文件 | 要复制的文件。 | 是,除非使用嵌套资源集合元素 |
preservelastmodified | 使复制文件的最后修改时间与原始源文件相同。 | 否;默认为 false |
tofile | 要复制到的文件。在 Apache Ant 1.8.2 之前,tofile 属性仅支持 文件资源 进行复制。 | 使用 file 属性,可以使用 tofile 或 todir。 使用嵌套资源集合元素,如果包含的资源数量大于 1,或者如果仅在 <fileset> 中指定了 dir 属性,或者如果还指定了 file 属性,则仅允许使用 todir。 |
todir | 要复制到的目录。 | |
overwrite | 即使目标文件更新,也覆盖现有文件。 | 否;默认为 false |
force | 覆盖只读目标文件。自 Ant 1.8.2 起 | 否;默认为 false |
filtering | 指示在复制过程中是否应使用 全局构建文件过滤器 进行令牌过滤。注意:即使未指定此属性,或其值为 false、 no或 off,嵌套的 <filterset> 元素也将始终使用。 |
否;默认为 false |
flatten | 忽略源文件的目录结构,并将所有文件复制到 todir 属性指定的目录中。请注意,您可以通过使用 flatten 映射器 来实现相同的效果。 | 否;默认为 false |
includeEmptyDirs | 复制 FileSet(s) 中包含的任何空目录。 | 否;默认为 true |
failonerror | 如果为 false,则记录警告消息,但不停止构建,当要复制的文件不存在或其中一个嵌套 fileset 指向不存在的目录或复制时发生错误。 |
否;默认为 true |
quiet | 如果为 true且 failonerror 为 false,则当要复制的文件不存在或其中一个嵌套 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 元素来定义文件名转换。<copy>
使用的默认映射器是 identity 映射器。
自 Ant 1.6.3 起,可以使用文件名映射器类型来代替映射器元素。
请注意,传递给映射器的源名称取决于您使用的资源集合。如果您使用 <fileset>
或任何其他提供基本目录的集合,则传递给映射器的名称将是相对于基本目录的相对文件名。在任何其他情况下,都将使用源的绝对文件名。
FilterSet 用于替换复制文件的令牌。要使用 FilterSet,请使用嵌套的 <filterset>
元素。
可以使用多个 filterset。
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
。