<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {mso-style-noshow:yes; mso-style-priority:99; color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {mso-style-noshow:yes; mso-style-priority:99; color:purple; mso-themecolor:followedhyperlink; text-decoration:underline; text-underline:single;} p {mso-style-noshow:yes; mso-style-priority:99; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:宋体; mso-bidi-font-family:宋体;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} -->
Ant 是一个java开发的优秀开源框架.
它可以完成以下任务: 程序的编泽,运行, 对硬盘上的文件操作(创建,删除,复制文件),打包成jar,war,ear,文件 等等好多任 务.
Ant 安装, 从网站上下载ant,一个zip包 不用安装,直接解压到硬盘上, 例如我的解压在D:/apache-ant-1.7.0 下
然后就是设置环境变量 右击 "我的电脑" -----"属性" ---"高级"-----"环境变量" 找到"系统环境变量" 里的 "path"
项, 点击 "编辑" 把 ant安装目录下的 bin 文件夹添加到 这儿就可以了,
以我的为例: ; D:/apache-ant-1.7.0/bin 注意: 把红色部分都添加到 "path" 项的最后 ,包括最前面那个 “逗号” 点击 “确定” . 打开dos 环境: 在任意目录下输入 ant , 如果出现以下提示:就表示你安装成功了
Buildfile: build.xml does not exist!
build failed
OK , 大功告成! 现在你可以用ant进行开发了.
(二) 具体学习
谈到java学习,每一个新框最快入门,是看框架自带的docs 和 例子,ant 也不例外
先打开ant的docs 看看 .它在安装目录下有一个doc文件夹下面.再下面还有一个文件夹 manual 打开它,里面有一个index.xml文件,用浏览器打开. 我的路径是在: D:/apache-ant-1.7.0/docs/manual/index.xml
里面点击“Ant tasks " 再点击 “Overview of Ant Tasks” 里面就是ant所有能完成的功能的api的介绍
想要使用ant :就只有一个build.xml文件的编辑. 把它搞定了,一切就OK 了,它要放在项目的根目录下
例: 在D:/ 新建一个项目, FirstAnt 那么 build.xml 要放在 FirstAnt 目录下
build.xml 文件的结构如下:
<?xml version="1.0" encoding="gb2312"?>
<project name="FirstAnt" default ="" basedir=".">
<property />
<target name="">
</target>
.
.
.
<target>
</target>
</project>
现在就可以看到 这个是build.xml的整个结构 就是一个 project 中包括一系列的 property , target
在<project> 中 name="FirstAnt" 表示整个工程的名字,这个名字可以随便取,不一定跟项目的名字一样
default ="" 是一个target 的名字 ,它表示先运行那个任务,
例: 在<project>中定义了两个target ,分别是 compile, run
在default="run" 表示ant先运行 "run" target
一个target只能被执行一次,即使有多个target依赖于它
basedir="." 表示在当前目录操作 (与build.xml在同一目录下操作,也就是在FirstAnt的根目录下)
在进行任务之前先要定义一系列 全局变量,以例以后引用,就要通过 property 属性了
例; <property name="src" value="src"/>
<property name="build" value="class"/>
现在我们定义了两个属性(全局变量),那么以后在targ中用过src ,和 class文件夹的时候,就可以以下用了
${src} 表示引用 src
${build} 表示引用class
项目初始化的任务
<target name="init">
<mkdir dir="${build}" />
<mkdir dir="${src}/com" />
</target>
这个任务的作用是 在FirstAnt 根目录下创建一个 class文件夹
在 src 文件夹下面创建一 com 文件夹
<javac> 学习:编译程序
那么现在项目初始化完了以后呢,就开始学习编译程序了
再定义一个target
<target name="compile" depends ="init">
<javac srcdir="${src}" destdir="${build}" >
<include name="**/*.java"/>
</javac>
</target>
这个任务的名字是"compile" depends="init" 它表示这个任务要依靠前面定义的"init" 任务.也就是等init任务完成了以后"compile" 任务才能执行.(但两个任务不一定排在一起执行, 只要保证"init" 在 "compile" 前面执行就行啦!)
再看里面具体的任务<javac> ,现在是看 帮助的时候了 但看" ant task" 列表中的 Compile tasks
里面有个javac 任务, 打开. 可以看到它有好多属性. 其中有一个 srcdir 属性 ,是必须有的,其它都是可选的
srcdir 表示要编译的java文件的源文件夹 例如 :我们现在定义的是 srcdir="${src}"
它可以配合 includes,includesfile, excludes ,excludesfile属性共同来完成 对文件的具体操作
(1) 如果什么都没有,只是<javac srcdir="${src}"> 的话,
只编译 src下的文件及子文件夹下的文件, 不能再深入
例: src 文件夹下有一个 second 文件夹 ,second文件夹下还有一个third文件夹
它只会编译 src 文件夹下的java文件 及 second文件夹下的java文件
不会编译 third 文件夹下的java文件
(2) 如果加上 includes 属性的话,就可能定义精确定义
例 <javac srcdir="${src}" ,includes="second2/*.java">
则只编译 src文件夹下second2文件件下的java文件,(但不包括src文件夹下的java文件)
(3) :includes 的选项可以是用 , 分隔的
例: <javac srcdir="${src}" , includes="second/*.java, second2/*.java">
只编译 second文件夹 second2 文件夹下的 java文件
(4) 用includesfile 属性:
必须写清楚文件的完整路径(绝对路径),
它只能用于一个文件,也就是不能使用 通配符
如: includesfile="second/Second.java" //它会在根目录下寻找 second文件夹,会隔过 src文件夹,所以提示
找不到此文件
这样写会正确 includesfile="src/second/Second.java"
但是 src 前面绝对不能加 "/" 这将表示 在当前盘符下下找 例如 d: ,这肯定是找不到的
行啦, 个人感觉这个属性不太好用,用includes就可以实现全部的功能,这儿就不多写了
(5) 用excludes 属性: 可以定义不编译的文件.(也就是在excludes中定义的文件都不会编译)
例: excludes="second2/*.java" 编译的时候不包括 second2文件夹下的文件
注意 excludes="second/Black.java" 编译的时候,也不编译second文件夹下的文件,并不是仅仅不编译
Black.java
对这四个属性的总结:
(1) includes ,excludes 中写路径的时候要直接写 ${src} 文件夹下的目录 如 second/*.java
includes 可以对多个文件起作用,对单个文件也起作用 例 : second/Second.java 中只对second文件夹下的
Second.java文件起作用
但 excludes 对单个文件的操作,它会认为是整个文件夹的操作 例 excludes="second/Second.java" 它会认为
second文件夹下的文件都不编译
(2) includesfile ,excludesfile 属性不能用通配符
(3) 如果想编译一个文件夹下的全部文件,用 includes 属性
如果不想译某个文件夹,则用 excludes属性
destdir 属性: 表示文件编译后输出的目录.
例 <javac srcdir="${src}" destdir="${build}" />
表示 class 目录为文件编译后的存放的目录
<java > 学习:运行程序
<java calsspath="${build}" classname="Person" fork="true">
classname属性:要运行类的名字 ,注意是编译后类名
例: classname="Person " (不要加后缀名 .java)
classpath :指定要运行名字的路径
jar 属性: 包含要运行类名的jar文件, 如果要用这个属性,fork 必须设置为true
fork="true" 表示在一个新的虚拟机中运行该类
文件操作: <copy> 学习:
file="1.txt" 要操作的文件名
todir ="" 拷贝目的文件夹
例 <copy file="${build}/add.jar" todir="${lib}"/>
把 class文件夹下的 add.jar文件,复制到 lib 文件夹下
copy命令还可以与<file> 命令一块用,功能更强大
<copy todir="${lib}">
<fileset dir="${build}">
<include name="1.txt"/>
<exclude name="2.txt"/>
<fileset>
</copy>
从build文件夹,下复制 1.txt到lib文件夹,但不要包括2.txt
通过 <fileset>可以精确定义
可 以把<fileset/>简写成<fileset dir="${basedir}/old" includes="old1.txt,old2.txt" /> includes可以理解成include的复数形式,包含多个文件时用逗号隔开,excludes也一样。
拷贝一个目录到指定目录下
例:<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将会自动创建这个路径。
拷贝单个的文件:
〈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就行了。