一本Ant详细的书:<Ant开发及整合应用详解>
http://book.csdn.net/bookfiles/379/index.html
Ant中copy操作学习心得
Appfuse的第一个ant命令是ant new,其任务是建立一个新命名的project,少不了会复制很多文件。build.xml中也有很多copy操作,为了搞清楚ant new到底干了些什么事,还是先把copy操作了解一下。看了会ant的DOCS,网上也找了些文章,发现copy这部分都是一带而过,讲得很浅,于是我就只有自己实验下,发现还有点收获。 ant版本为1.6.5。
1. 拷贝单个文件到指定目录下。
例:<copy todir="${basedir}/new" file="${basedir}/old/old1.txt1">
将${basedir}/old/old.txt文件拷贝到${basedir}/new下
2. 拷贝一批文件到指定目录下
例:<copy todir="${basedir}/new">
<fileset dir="${basedir}/old">
<include name="old1.txt" />
<include name="old2.txt" />
<exclude name="old8.txt" />
</fileset>
</copy>
这里fileset定义的是原文件的组成形式,<include/>子属性表示包括,<exclude/>子属性表示排除,很简单,通过他们组合实现多文件的筛选,当然我这个例子用得很傻。比如
<include name="appgen/**"/>
<include name="ibatis/**"/>
<exclude name="**/*.log"/>
拷贝appget目录和ibatis目录下除了.log文件以外的其它所有文件和子目录。
可以把<fileset/>简写成<fileset dir="${basedir}/old" includes="old1.txt,old2.txt" />,includes可以理解成include的复数形式,包含多个文件时用逗号隔开,excludes也一样。
3. 拷贝一个目录到指定目录下
例:<copy todir="${basedir}/new">
<fileset dir="${basedir}/old">
<include name="appgen" />
<include name="appgen/" />
<include name=appgen/**" />
<include name="appgen/***" />
</fileset>
</copy>
同样使用<fileset/>属性,name指定目录名,不过这里要分两种情况,用<include/>子属性和不用<include/>子属性.
若使用<include/>, 又要分三种情况
若是“appgen”,则只会拷贝名为appgen的空目录过去,它里面的文件和子目录则不会拷贝。
若是“appgen/”,或“appgen/**”,则会把整个appgen目录拷贝过去,包括里面的文件和子目录。
若是“appgen/*”,则只会把该目录和该目录下第一级子目录的所有东西拷贝过去,而不会拷贝第二级和第二级以下的。注:“appgen/*”这儿是一个*号,*号若大于两个,也跟一个*号是同样效果。比如“appgen/*”和“appgen/****”都只拷贝appgen目录下第一级子目录。
注:若appeng这个目录本身就是个空目录,无论怎么写,这个空目录都不会被拷贝。也就是说,copy操作不会产生创建空目录的作用,要想创建空目录,只有用mkdir。
若不使用任何<include>属性,如
<fileset dir="${basedir}/old">
</fileset>
则会拷贝${basedir}/old下的所有文件和子目录。
注:使用<exclude/>排除目录时,目录名必须写成“appgen/”或“appgen/**”形式,否则不会生效。
以上是三种拷贝到目录的种类,注意如果计算机中没有todir指定的路径,ant将会自动创建这个路径。
4. 拷贝单个的文件:
〈copy tofile="old.txt" file="new.txt" /〉就这么简单就行了。
当然也可以写成
<copy tofile="${basedir}/new/new.txt">
<fileset dir="${basedir}/old" includes="old.txt" />
</copy>
这里includes就只能写一个文件,不能写上多个文件,因为不能将多个文件复制到一个文件中去,所以这样麻烦的写法是没有意义的。
复制肯定还要涉及到同名覆盖的问题,ant在copy类的API中说明:Files are only copied if the source file is newer than the destination file,这里的newer是指文件的修改时间,即使你在修改时文件内容没有任何变化,只是导致修改时间变了,ant同样会覆盖同名文件,也就是说,ant不会检查文件内容。
对于是复制目录的情况,由于目录没有修改时间,ant还是通过检查目录内文件的修改时间来决定是否覆盖的,若目录内某文件修改时间有变化,则会覆盖这个文件,而不是整个目录。
如果要强行覆盖,<copy/>有个overwrite属性,默认为false,改成true就行了。
Delete Task:对文件和目录进行删除
Delete 任务可用于删除一个或多个文件,或删除一个或多个目录和目录下的文件。默认时不会删除空目录,要删除空目录可以设定includeEmptyDirs属性为true。在Delete任务中可以使用FileSet和DirSet类型。
4.6.1 Delete Task的属性及功能
Delete任务包括以下属性:
(1)file:用于指定要删除的文件的名称,可以为相对路径或绝对路径。
(2)dir:指定一个将要被删除的根目录。这个目录下的子目录及文件将可能被删除。dir属性和file属性两者必须指定其一。
(3)verbose:作用是指定是否在命令行中输出被删除的文件的名称。默认为false。
(4)quiet:作用是指定当要被删除的文件或目录不存在时是否不显示提示信息。默认为false,代表要显示提示信息。
(5)failonerror:用于指定当出现错误时是否停止执行命令。
(6)includeemptydirs:表明当使用FileSet类型时是否删除空的目录。
(7)includes:用于指定将要删除的文件或目录的模式。可用逗号或空格符进行分隔。
(8)includesfile:用于指定要删除的文件的模式。已不建议使用。
(9)excludes:用于指定一个或多个文件模式或目录模式。这些符合条件的文件和目录将不被删除。
(10)excludesfile:用于指定将不被删除的文件模式,已不建议使用。
(11)defaultexcludes:用于指定是否使用Ant默认的default excludes模式,已不建议使用。
(12)deleteonexit:用于指定是否采用Java File类中的deleteOnExit()方法进行判断,如果使用这个方法,那么仅当存在文件时才进行删除,默认取值为false。
4.6.2 在执行Delete Task时使用文件过滤的实例
(1)删除单个文件的实例:
<delete file="/lib/ant.jar"/>
这个例子的作用是删除lib目录下的ant.jar文件。
(2)删除目录的实例:
<delete dir="lib"/>
这个例子的作用是删除lib目录,包括这个目录的所有子目录及文件,可以通过include或exclude类型指定删除的部分文件,而不是目录下的所有文件。
(3)删除所有备份文件和空的目录的例子:
<delete includeEmptyDirs="true">
<fileset dir="." includes="**/*.bak"/>
</delete>
这个例子的作用是删除当前目录以及其子目录下的所有.bak文件,同时也删除所有空的目录。
Ant Delete 如何只删掉文件夹下所有文件和文件夹
用fileset 来过滤要删掉的目录和文件
<delete verbose="true" includeemptydirs="true">
<fileset dir="${buildDir}">
<include name="**/*"/>
</fileset>
</delete>
注:includeemptydirs 的意思是就算文件夹是空的,也同样删除。
这样就会避免使用像
<delete dir="build"></delete>
这样就会把build文件夹以及下面的所有子目录一起删掉。
很多时候父目录是没有必要每次都删了重建的,只要清空这个文件夹就好了。
常用到的模版:
xml version="1.0" encoding="UTF-8"?>
<!-- name:对应工程的名字;default:需要的缺省任务(运行"ant"不指明任务时执行的任务) -->
<project name="WebTest" default="dist" basedir=".">
<property name="appName" value="WebTest"/>
<property name="src.dir" value="src"/>
<property name="lib.dir" value="lib"/>
<property name="dist.dir" value="dist"/>
<property name="classes.dir" value="bin"/>
<property name="webapps.dir" value="D:/jakarta-tomcat-5.0.28/webapps/WebTest"/>
<property name="webroot.dir" value="WebRoot"/>
<property name="config.dir" value="config"/>
<path id="compile.classpath">
<pathelement location="${classes.dir}"/>
<fileset dir="${lib.dir}" includes="**/*.jar" />
path>
<target name="clean" description="Delete old build and dist directories">
<delete dir="${clesses.dir}"/>
<delete dir="${dist.dir}"/>
<delete dir="${webapps.dir}"/>
target>
<target name="prepare">
<mkdir dir="${classes.dir}"/>
<mkdir dir="${dist.dir}"/>
target>
<target name="compile" depends="prepare" description="Compile java sources">
<javac srcdir="${src.dir}" destdir="${classes.dir}" debug="true">
<classpath refid="compile.classpath"/>
javac>
<copy todir="${classes.dir}">
<fileset dir="${src.dir}">
<include name="**/*.xml"/>
<include name="**/*.properties" />
fileset>
copy>
target>
<target name="deploy" depends="compile" description="Deploy application to servlet container">
<mkdir dir="${webapps.dir}"/>
<copy todir="${webapps.dir}">
<fileset dir="${webroot.dir}"/>
copy>
<mkdir dir="${webapps.dir}/WEB-INF/classes"/>
<copy todir="${webapps.dir}/WEB-INF/classes">
<fileset dir="${classes.dir}" >
<include name="**/**" />
fileset>
copy>
<mkdir dir="${webapps.dir}/WEB-INF/lib"/>
<copy todir="${webapps.dir}/WEB-INF/lib">
<fileset dir="${lib.dir}" includes="*.jar" />
copy>
<copy todir="${webapps.dir}/WEB-INF/">
<fileset dir="${config.dir}"/>
copy>
target>
<target name="dist" depends="clean,deploy" description="Create binary destribution">
<jar jarfile="${dist.dir}/${appName}.war" basedir="${webapps.dir}"/>
target>
<target name="javadoc" depends="compile" description="Create Javadoc API documentation">
<mkdir dir="${dist.dir}/docs/api"/>
<javadoc sourcepath="${src.dir}" destdir="${dist.dir}/docs/api" packagenames="duzn.ant.test.*"/>
target>
project>