以下代码演示了ant
文件copy
任务与globmapper
的行为。我想复制一套文件。在复制一些需要重命名的文件时,请选择与模式匹配的文件。我认为匹配模式的文件将用新名称复制,其他文件则用原始名称复制。
这是错误的:如果源集包含与模式不匹配的文件,它们将被静默地忽略。
<project name="trial" default="test" basedir=".">
<target name="test">
<property name="mydir" value="${java.io.tmpdir}/demo/src"/>
<mkdir dir="${mydir}" />
<touch file="${mydir}/abc0.txt"/>
<touch file="${mydir}/abc1.java"/>
<touch file="${mydir}/abc2.java"/>
<property name="dest" value="${java.io.tmpdir}/demo/dest"/>
<copy todir="${dest}" >
<fileset dir="${mydir}">
<include name="**/*.java"/>
<include name="**/*.txt"/>
</fileset>
<globmapper from="*.txt" to="*.bak"/>
</copy>
</target>
<target name="clean" >
<delete dir="${java.io.tmpdir}/demo"/>
</target>
</project>
简单的ant输出并不表示某些文件已被复制。
test:
[mkdir] Created dir: C:cygwin64tmpdemosrc
[touch] Creating C:cygwin64tmpdemosrcabc0.txt
[touch] Creating C:cygwin64tmpdemosrcabc1.java
[touch] Creating C:cygwin64tmpdemosrcabc2.java
[copy] Copying 1 file to C:cygwin64tmpdemodest
BUILD SUCCESSFUL
Total time: 0 seconds
调试ant -v
的输出
Setting project property: mydir -> C:cygwin64tmp/demo/src
[mkdir] Created dir: C:cygwin64tmpdemosrc
[touch] Creating C:cygwin64tmpdemosrcabc0.txt
[touch] Creating C:cygwin64tmpdemosrcabc1.java
[touch] Creating C:cygwin64tmpdemosrcabc2.java
Setting project property: dest -> C:cygwin64tmp/demo/dest
fileset: Setup scanner in dir C:cygwin64tmpdemosrc with patternSet{ includes: [**/*.java, **/*.txt] excludes: [] }
[copy] abc0.txt added as abc0.bak doesn't exist.
[copy] C:cygwin64tmpdemosrcabc1.java skipped - don't know how to handle it
[copy] C:cygwin64tmpdemosrcabc2.java skipped - don't know how to handle it
[copy] No sources found.
[copy] Copying 1 file to C:cygwin64tmpdemodest
[copy] Copying C:cygwin64tmpdemosrcabc0.txt to C:cygwin64tmpdemodestabc0.bak
BUILD SUCCESSFUL
Total time: 0 seconds
我现在理解了这种行为(以及可能的修复方法),但在这种情况下,我能强迫蚂蚁出错吗?
<firstmatchmapper>
包含嵌套映射器,这些映射器将应用于文件,直到其中一个嵌套映射器匹配。。。
<copy todir="${dest}" >
<fileset dir="${mydir}">
<include name="**/*.java"/>
<include name="**/*.txt"/>
</fileset>
<firstmatchmapper>
<globmapper from="*.txt" to="*.bak"/>
<identitymapper/>
</firstmatchmapper>
</copy>
输出
[copy] Copying 3 files to C:cygwintmpdemodest
[copy] Copying C:cygwintmpdemosrcabc0.txt to C:cygwintmpdemodestabc0.bak
[copy] Copying C:cygwintmpdemosrcabc1.java to C:cygwintmpdemodestabc1.java
[copy] Copying C:cygwintmpdemosrcabc2.java to C:cygwintmpdemodestabc2.java
请注意,abc0.txt
的扩展名更改为.bak
,但其他文件的.java
扩展名保持不变。
解释
在上面的例子中,<firstmatchmapper>
包含两个映射器:
<globmapper from="*.txt" to="*.bak"/>
<identitymapper/>
对于abc0.txt
:
abc0.txt
与<globmapper from="*.txt" ...>
匹配,因此应用<globmapper from="*.txt" to="*.bak"/>
得到abc0.bak
- 由于已经存在匹配,因此跳过
<identitymapper/>
对于abc1.java
:
abc1.java
与<globmapper from="*.txt" ...>
不匹配,因此跳过此映射程序- 由于还没有匹配,因此应用了
<identitymapper/>