<!-- /* 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就行了。