基于目录的任务

一些任务使用目录树来执行它们的操作。例如,javac 任务,它将包含 .java 文件的目录树编译成 .class 文件,就是这些基于目录的任务之一。由于这些任务中的一些任务对目录树进行了大量的操作,因此任务本身可以充当隐式的 FileSet

无论文件集是隐式的还是显式的,在使用这些基于目录的任务时,对目录树的子集进行操作通常非常有用。本节介绍如何在使用这些基于目录的任务时选择目录树的子集。

Apache Ant 提供了两种方法来创建文件集的子集,这两种方法可以同时使用

Patternset

我们说过基于目录的任务有时可以充当隐式的 <fileset>,但除此之外,FileSet 还充当隐式的 <patternset>

隐式 PatternSet 的包含和排除元素可以通过以下方式在基于目录的任务(或显式文件集)中指定:

在处理外部文件时,文件的每一行都被视为添加到包含或排除模式列表中的模式。

当同时使用包含和排除时,只有与至少一个包含模式匹配且不与任何排除模式匹配的文件/目录才会被使用。如果没有给出包含模式,则假定所有文件都与包含模式匹配(可能除了默认排除项之外)。

模式

如前所述,模式用于包含和排除文件。这些模式看起来非常像 DOS 和 UNIX 中使用的模式

* 匹配零个或多个字符,? 匹配一个字符。

通常,模式被认为是相对于任务相关的基目录的相对路径(对于 <fileset>,基目录是 dir 属性)。只有在该基目录下找到的文件才会被考虑。因此,虽然像 ../foo.java 这样的模式是可能的,但它不会匹配任何内容,因为永远不会扫描基目录的父目录以查找文件。

示例

*.java  匹配  .javax.javaFooBar.java,但不匹配 FooBar.xml(不以 .java 结尾)。

?.java  匹配  x.javaA.java,但不匹配 .javaxyz.java(两者在 .java 之前都没有一个字符)。

允许 *? 的组合。

匹配是在每个目录中进行的。这意味着首先将模式中的第一个目录与要匹配的路径中的第一个目录进行匹配。然后匹配第二个目录,依此类推。例如,当我们有模式 /?abc/*/*.java 和路径 /xabc/foobar/test.java 时,第一个 ?abcxabc 匹配,然后 *foobar 匹配,最后 *.javatest.java 匹配。它们都匹配,因此路径与模式匹配。

为了使事情更加灵活,我们添加了一个额外的功能,它可以匹配多个目录级别。这可以用来匹配完整的目录树,或者匹配目录树中任何位置的文件。为此,必须使用 ** 作为目录的名称。当 ** 在模式中用作目录的名称时,它匹配零个或多个目录。例如:/test/** 匹配 /test/ 下的所有文件/目录,例如 /test/x.java/test/foo/bar/xyz.html,但不匹配 /xyz.xml

有一个“简写”:如果模式以 /\ 结尾,则会追加 **。例如,mypackage/test/ 被解释为 mypackage/test/**

示例模式
示例 解释
**/CVS/* 匹配目录树中任何位置的 CVS 目录中的所有文件。
匹配
CVS/Repository
org/apache/CVS/Entries
org/apache/jakarta/tools/ant/CVS/Entries
但不匹配
org/apache/CVS/foo/bar/Entries
(foo/bar/ 部分不匹配)
org/apache/jakarta/** 匹配 org/apache/jakarta 目录树中的所有文件。
匹配
org/apache/jakarta/tools/ant/docs/index.html
org/apache/jakarta/test.xml
但不匹配
org/apache/xyz.java
(jakarta/ 部分缺失)。
org/apache/**/CVS/* 匹配 org/apache 下目录树中任何位置的 CVS 目录中的所有文件。
匹配
org/apache/CVS/Entries
org/apache/jakarta/tools/ant/CVS/Entries
但不匹配
org/apache/CVS/foo/bar/Entries
(foo/bar/ 部分不匹配)
**/test/** 匹配路径中包含 test 元素的所有文件,包括 test 作为文件名。

当这些模式用于包含和排除时,您将拥有一个强大的方法来选择您想要的文件。

选择器

无论在基于目录的任务中是隐式的还是显式的,<fileset> 也充当 <and> 选择器容器。这可以用来为任务应该处理的文件创建任意复杂的选择条件。有关更多信息,请参阅 Selector 文档。

标准任务/文件集

Ant 中的许多标准任务都接受一个或多个文件集,这些文件集遵循此处给出的规则。此列表是这些任务的子集,是可以用作隐式文件集的标准 Ant 任务列表

示例

<copy todir="${dist}">
  <fileset dir="${src}"
           includes="**/images/*"
           excludes="**/*.gif"/>
</copy>

这将把由 ${src} 定义的目录树中所有名为 images 的目录中的所有文件复制到由 ${dist} 定义的目标目录中,但将所有 *.gif 文件从复制中排除。

<copy todir="${dist}">
  <fileset dir="${src}">
    <include name="**/images/*"/>
    <exclude name="**/*.gif"/>
  </fileset>
</copy>

与上面的示例相同,但使用嵌套元素表示。

<delete dir="${dist}">
    <include name="**/images/*"/>
    <exclude name="**/*.gif"/>
</delete>

删除原始文件集,delete 任务可以充当隐式文件集。

默认排除项

有一组定义,默认情况下从所有基于目录的任务中排除。从 Ant 1.8.1 开始,它们是

**/*~
**/#*#
**/.#*
**/%*%
**/._*
**/CVS
**/CVS/**
**/.cvsignore
**/SCCS
**/SCCS/**
**/vssver.scc
**/.svn
**/.svn/**
**/.DS_Store

从 Ant 1.8.2 开始,添加了额外的默认排除项

**/.git
**/.git/**
**/.gitattributes
**/.gitignore
**/.gitmodules
**/.hg
**/.hg/**
**/.hgignore
**/.hgsub
**/.hgsubstate
**/.hgtags
**/.bzr
**/.bzr/**
**/.bzrignore

如果您不想应用这些默认排除项,可以使用 defaultexcludes=no 属性禁用它们。

这是默认列表;请注意,您可以使用 defaultexcludes 任务修改默认排除项列表。