## 1.定位文件
Project類中有一個file方法可以用來定位文件。
build.gradle:
~~~
File configFile = file('src/config.xml')
configFile = file(configFile.absolutePath)
println configFile.path
configFile = file(new File('src/config.xml'))
~~~
執行gradle -q命令:
~~~
D:\GRADLE~2\0112>gradle -q
D:\gradle_product\0112\src\config.xml
Welcome to Gradle 2.2.1.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
~~~
雖然我們目錄中沒有src\config.xml。但是file方法仍然定位了該文件,且能正確輸出文件的絕對路徑。
從上面的腳本中可以看出,file方法可以接受字符串和File對象作為參數。file方法一般都會將項目的根目錄作為默認的父目錄,而不是當前工作目錄。
## 2.文件集合-FileCollection
項目集合在gradle中用FileCollection接口來表示。而且gradle中很多對象都是實現該接口的,例如依賴配置就是實現該接口的。
調用Project.files()方法可以獲得FileCollection實例,你可以傳入任意數量的對象,然后會被轉換為File對象的集合,下面創建一個FileCollection集合。
~~~
FileCollection collection = files('src/file1.txt',new File('src/file2.txt'),['src/file3.txt','src/file4.txt'])
~~~
上面的files方法里傳入的參數真是“亂其八糟”的,有字符串,文件,文件集合。下面來看看文件集合的一些特性:
#### 可迭代
文件結合是可迭代的,支持下面的操作:
as操作符:將集合轉化為其他類型
+操作符:合并2個文件集合
-操作符:從一個集合扣除一個集合
看下面一個綜合的例子:
~~~
FileCollection collection = files('src/file1.txt'
,new File('src/file2.txt'),
['src/file3.txt', 'src/file4.txt'])
collection.each{File file ->
println file.name
}
Set set = collection.files
Set set2 = collection as Set
List list = collection as List
String path = collection.asPath
def union = collection + files('src/file5.txt')
def different = collection - files('src/file5.txt')
~~~
執行命令:
~~~
D:\GRADLE~2\0112>gradle -q
file1.txt
file2.txt
file3.txt
file4.txt
Welcome to Gradle 2.2.1.
To run a build, run gradle <task> ...
To see a list of available tasks, run gradle tasks
To see a list of command-line options, run gradle --help
~~~
#### 閉包和可回調方法
~~~
task list << {
File srcDir
// Create a file collection using a closure
FileCollection collection = files { srcDir.listFiles() }
srcDir = file('src')
println "Contents of $srcDir.name"
collection.collect { relativePath(it) }.sort().each { println it }
srcDir = file('src2')
println "Contents of $srcDir.name"
collection.collect { relativePath(it) }.sort().each { println it }
}
~~~
build.gradle在之前的基礎上添加了一個list任務,可以看到files方法中傳入的是什么?是一個閉包代碼塊,然后當調用sort()方法來查詢集合內容的時候,才會調用閉包代碼塊,所以srcDir寫在了collection的定義后。
## 3.文件的樹形結構-FileTree
FileTree接口繼承于FileCollection接口,在gradle中有一些對象是繼承FileTree,比如SourseSet。
#### 獲得FileTree對象
Project.fileTree方法,
~~~
FileTree tree = fileTree(dir: 'src/main')
tree.include '**/*.java'
tree.exclude '**/Abstract*'
tree = fileTree('src').include('**/*.java')
tree = fileTree('src') {
include '**/*.java'
}
tree = fileTree(dir: 'src', include: '**/*.java')
tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml'])
tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**')
~~~
第一個定義中,是將src/main目錄(包括子目錄的子目錄)下的文件生成fileTree文件,包括以java結尾的文件,不包括已Abstract開頭的文件。
第二個定義中,采用連寫的方式,包括src目錄下的所有的java文件。
第三個定義中,類似第二種,只是采用的方式是閉包形式來定義所包含的文件。
第四種-第六中,根據構造函數的重載特性,傳入不同的參數創建的。
#### 使用FileTree對象
~~~
task findTree(dependsOn:'create') <<{
FileTree filtered = tree.matching{
include 'org/gradle/api/**'
}
FileTree sum = tree + fileTree(dir:'src/test')
tree.visit{
element ->
println "$element.relativePath =>$element.file"
}
}
task create {
File testFile = file('src/test/java')
testFile.mkdirs()
}
~~~
執行命令
~~~
D:\GRADLE~2\0112>gradle -q findTree
main =>D:\gradle_product\0112\src\main
main/java =>D:\gradle_product\0112\src\main\java
test =>D:\gradle_product\0112\src\test
test/java =>D:\gradle_product\0112\src\test\java
~~~
## 4.由壓縮文件得到FileTree
針對壓縮文件有2個方法zipTree和tarTree兩個方法。
~~~
FileTree zip = zipTree('someFile.zip')
FileTree tar = tarTree('someFile.tar')
FileTree someTar = tarTree(resources.gzip('someTar.ext'))
~~~
## 5.指定輸入文件的集合
~~~
compile{
source = file('src/main/java')
}
compile{
source = 'src/main/java'
}
compile{
source = ['src/main/java','../shared/java']
}
compile{
source={
file('src').listFiles.findAll{
it.name.endsWith('.zip')
}.collect{
zipTree(it)
}
}
}
~~~
上面的4中方式都是重新設置了source文件夾的位置,也就是輸入文件的位置。
Project下還有一個source方法來定義輸入文件。
~~~
compile{
source 'src/main/java','src/main/groovy'
source file('../shared/java')
source{
file('src/test').listFiles()
}
}
~~~
## 6.復制文件
繼承Copy對象來復制文件
~~~
task copyTask(type:Copy){
from 'src/main/webapp'
into 'build/explodedWar'
}
~~~
from定義要被復制的文件目錄,into定義的是復制到的目錄。
from的來源有很多,類似files()
1.目錄:目錄下的所有文件都會包含在內
2.文件
3.不存在的文件:忽略
4.任務:任務的輸出文件
into方法類似file方法
~~~
task copyTask(type:Copy){
from 'src/main/webapp'
into 'build/explodedWar'
}
task copyTaskWithPaths(type:Copy){
from 'src/main/webapp'
into 'build/explodedWar'
include '**/*.html'
include '**/*.jsp'
exclude{
details ->details.file.name.endsWith('/html')&&
details.file.text.contains('staging')
}
}
task anotherCopyTask(type:Copy){
from 'src/main/webapp'
from 'index.html'
from copyTask
from copyTaskWithPaths.outputs
from zipTree(asserts.zip)
into {
getDestDir()
}
}
~~~
任務copyTaskWithPaths可以來刪選所選目錄中的文件。
anotherCopyTask任務說明from的來源有多種形式。
還有一種復制文件的方式是調用Project的copy方法,需要注意的一點是,在任務中使用copy方法,必須顯示的定義輸入和輸出文件。
~~~
task copyMethod <<{
copy{
from 'src/main/webapp'
into 'build/explodedWar'
include '**/*.html'
include '**/*.jsp'
}
}
~~~
## 7.重命名文件
~~~
task rename(type:Copy){
from 'src/main/webapp'
into 'build/explodedWar'
rename{
String fileName->
fileName.replace('1','2')
}
}
~~~
上面的任務是將src/main/webapp目錄下的文件移到build/explodedWar下,在移動后,將文件名為1的文件重命名為2。

~~~
task rename(type:Copy){
from 'src/main/webapp'
into 'build/explodedWar'
rename{
String fileName->
fileName.replace('1','2')
}
rename '(.+)1(.+)','$1$2'
rename(/(.+)1(.+)/,'$1$2')
}
~~~
第2個和第三個rename中,使用了正則表達式。$1表示表達式中第一個匹配項。
## 8.過濾文件
~~~
import org.apache.tools.ant.filters.FixCrLfFilter
import org.apache.tools.ant.filters.ReplaceTokens
task filter(type:Copy){
from 'src/main/webapp'
into 'build/explodedWar'
expand(copyright:'2009',version:'2.3.2')
expand(project.properties)
filter(FixCrLfFilter)
filter(ReplaceTokens,tokens:[copyright:'2009',version:'2.3.1'])
filter{
"[$line]"
}
}
~~~
expand 和filter都是尋找一個叫token的東西,形式有點像@tokenName@
## 9.CopySpec的使用
復制規范形成一個層次結構。一份規范繼承目的地路徑,包括模式、排除模式,復制操作,名稱映射和過濾器。嵌套復制:
~~~
task nestedSpecs(type:Copy){
into 'build/explodedWar'
exclude '**/*staging'
from('src/dist'){
include '**/*.html'
}
into('libs'){
from configurations.runtime
}
}
~~~
但是執行的時候報錯。是因為我們沒有定義runtime的依賴,所以會報如下錯誤。
~~~
qianhuis-Mac-mini:0112 qianhui$ gradle -q nestedSpecs
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/qianhui/Documents/Developer/gradle_project/0112/build.gradle' line: 8
* What went wrong:
A problem occurred evaluating root project '0112'.
> Could not find property 'runtime' on configuration container.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
~~~
## 10 .Sync任務
同步任務繼承與copy任務,當它執行的時候,將source文件copy到目標目錄中,然后刪除目標文件中不是copy過來的文件。
~~~
task libs(type:Sync){
from configurations.runtime
into "$buildDir/libs"
}
repositories{
mavenCentral()
}
dependencies{
runtime 'junit:junit:4.11'
}
~~~
將runtime運行時所依賴的jar文件復制到build/libs目錄下。
## 11.壓縮文件
~~~
apply plugin:'java'
version = 1.0
task myZip(type:Zip){
from 'src'
}
println myZip.archiveName
println relativePath(myZip.destinationDir)
println relativePath(myZip.archivePath)
~~~
執行命令輸出:
~~~
qianhuis-Mac-mini:0112 qianhui$ gradle -q myZip
0112-1.0.zip
build/distributions
build/distributions/0112-1.0.zip
~~~
- 前言
- gradle學習(1)-helloworld
- gradle學習(2)-基礎語法
- gradle學習(3)-基礎認識
- gradle學習(4)-構建java項目
- gradle學習(5)-創建eclipse項目
- gradle學習(6)-依賴管理
- gradle學習(7)-groovy
- gradle學習(8)-gradle的命令行
- gradle學習(9)-獲取build相關信息
- gradle學習(10)-gui
- gradle學習(11)-編寫構建腳本
- gradle學習(12)-groovy一些基礎語法
- gradle學習(13)-有的沒的
- gradle學習(14)-任務
- gradle學習(15)-任務
- gradle學習(16)-操作文件
- gradle學習(17)-被合并的ant
- gradle學習(18)-ant的屬性
- gradle學習(19)-log系統
- gradle學習(20)-詳解java插件
- gradle學習(21)-在eclipse中構建java項目
- gradle復習(1)-2種定義任務方式的區別
- gradle復習(2)-eclipse中添加依賴jar包
- gradle復習(3)-在gradle項目中使用TestNG
- gradle復習(4)-Cannot find System Java Compiler
- gradle復習(5)-Test remote debug
- gradle復習(6)-深入Jacoco
- gradle復習(7)-深入Jacoco
- gradle復習(8)-Task中行為
- gradle學習(22)-Sonar
- gradle學習(23)-Sonar runner