Gradle 文件操作

在Android工程的編譯和構(gòu)建過程中蓄坏,絕大多數(shù)的工作都涉及到了Gradle相關(guān)的文件操作究履。

文件對(duì)象


在工程目錄下策州,我們可以通過File的構(gòu)造方法來快速定位一個(gè)文件并創(chuàng)建相應(yīng)的File對(duì)象:

// 傳入文件的相對(duì)路徑
File configFile = new File('src/config.xml')

// 傳入文件的絕對(duì)路徑
configFile = new File(configFile.absolutePath)

// 通過相對(duì)路徑構(gòu)建一個(gè) java.nio.file.Path 對(duì)象并傳入
configFile = new File(Paths.get('src', 'config.xml'))

// 讀取property變量構(gòu)建 java.nio.file.Path 對(duì)象并傳入
configFile = new File(Paths.get(System.getProperty('user.home')).resolve('global-config.xml'))

之所以推薦用new File()的方式來創(chuàng)建對(duì)應(yīng)文件的對(duì)象而非 Project.file(java.lang.Object)
方法麻昼,主要是因?yàn)?file()方法總是把所傳入的路徑當(dāng)作以當(dāng)前工程目錄的相對(duì)路徑來進(jìn)行解析宵统,而不是當(dāng)前工作目錄。

文件集合


文件集合FileCollection
這個(gè)接口描述了針對(duì)一組文件的操作和屬性拳缠。在Gradle中,許多類都繼承了這一接口贸弥,例如依賴配置對(duì)象dependency configurations .
與創(chuàng)建File對(duì)象不同窟坐,創(chuàng)建FileCollection對(duì)象的唯一方式是通過 Project.files(java.lang.Object[])
方法,該方法的入?yún)?shù)目是任意多個(gè)绵疲,類型也可以是表示相對(duì)路徑的字符串哲鸳,F(xiàn)ile對(duì)象,甚至是集合盔憨,數(shù)組等徙菠。

FileCollection collection = files('src/file1.txt',
                                  new File('src/file2.txt'),
                                  ['src/file3.txt', 'src/file4.txt'],
                                  Paths.get('src', 'file5.txt'))

對(duì)于一個(gè)FileCollection對(duì)象,我們可以對(duì)它進(jìn)行各種操作:

// 遍歷文件集合
collection.each { File file ->
    println file.name
}

// 將FileCollection對(duì)象轉(zhuǎn)換為其他類型
Set set = collection.files
Set set2 = collection as Set
List list = collection as List
String path = collection.asPath
File file = collection.singleFile
File file2 = collection as File

// 對(duì)FileCollection進(jìn)行加減操作
def union = collection + files('src/file3.txt')
def different = collection - files('src/file3.txt')

files()方法也可以接受closure或者Callable對(duì)象作為入?yún)⒂粞遥?dāng)FileCollection中文件內(nèi)容被請(qǐng)求時(shí)closure或Callable會(huì)被回調(diào)婿奔,并轉(zhuǎn)換為一個(gè)File對(duì)象的Set返回。

task list {
    doLast {
        File srcDir

        // 使用closure創(chuàng)建一個(gè)FileCollection對(duì)象
        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 }
    }
}

File Trees


接口FileTree
是用于描述一個(gè)樹狀結(jié)構(gòu)文件集合的對(duì)象问慎,它不僅可以表示一個(gè)目錄下的文件結(jié)構(gòu)萍摊,還可以描述一個(gè)zip文件中內(nèi)容。
通過Project對(duì)象的fileTree方法如叼,我們可以創(chuàng)建一個(gè)目錄的FileTree對(duì)象冰木。

//創(chuàng)建以src/main為根目錄的FileTree
FileTree tree = fileTree(dir: 'src/main')

// 為FileTree添加include和exclude規(guī)則
tree.include '**/*.java'
tree.exclude '**/Abstract*'

// 使用路徑創(chuàng)建FileTree
tree = fileTree('src').include('**/*.java')

// 使用closure創(chuàng)建FileTree
tree = fileTree('src') {
    include '**/*.java'
}

//使用map創(chuàng)建FileTree
tree = fileTree(dir: 'src', include: '**/*.java')
tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml'])
tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**')

由于使用FileTree繼承了FileCollection接口,所以也可以向操作FileCollection那樣操作FileTree笼恰。

// 遍歷
tree.each {File file ->
    println file
}

//根據(jù)規(guī)則過濾
FileTree filtered = tree.matching {
    include 'org/gradle/api/**'
}

// 合并兩棵FileTree
FileTree sum = tree + fileTree(dir: 'src/test')

// 訪問樹結(jié)構(gòu)的每個(gè)結(jié)點(diǎn)
tree.visit {element ->
    println "$element.relativePath => $element.file"
}

上面提到踊沸,我們可以把例如zip或tar的壓縮文件當(dāng)做FileTree對(duì)象來處理。通過Project的zipTree和tarTree文件社证,我們可以根據(jù)zip文件或tar文件創(chuàng)建出對(duì)應(yīng)的FileTree對(duì)象逼龟。

FileTree zip = zipTree('someFile.zip')

FileTree tar = tarTree('someFile.tar')

復(fù)制文件


通過 Copy
Task,我們可以方便靈活地進(jìn)行文件的copy操作追葡。在copy的過程中审轮,我們還可以進(jìn)行文件的重命名肥哎,過濾等操作,這都得益于Copy Task繼承了CopySpec
接口來讓我們指定所要進(jìn)行的操作疾渣。

task anotherCopyTask(type: Copy) {
    //指定所要copy的源文件/源目錄
    // copy 目錄src/main/webapp下所有文件
    from 'src/main/webapp'
    // Copy 單個(gè)文件
    from 'src/staging/index.html'
    // Copy copyTask的輸出作為源文件
    from copyTask
    // Copy TaskWithPatterns.outputs
    from copyTaskWithPatterns.outputs
    // Copy Zip 文件中的內(nèi)容
    from zipTree('src/main/assets.zip')
    // 指定copy操作的輸出目錄
    into { getDestDir() }
    //通過正則表達(dá)式或者closure來指定copy過程中包含或排除的文件
    include '**/*.html'
    include '**/*.jsp'
    exclude { details -> details.file.name.endsWith('.html') &&
                         details.file.text.contains('staging') }
    }

如果copy任務(wù)簡(jiǎn)單篡诽,也可以使用Project.copy(org.gradle.api.Action)
方法來進(jìn)行文件copy。

task copyMethod {
    doLast {
        copy {
            from 'src/main/webapp'
            into 'build/explodedWar'
            include '**/*.html'
            include '**/*.jsp'
        }
    }
}

在文件copy過程中榴捡,我們可以遍歷所要操作的文件杈女,對(duì)文件本身進(jìn)行處理和操作。

import org.apache.tools.ant.filters.FixCrLfFilter
import org.apache.tools.ant.filters.ReplaceTokens
task rename(type: Copy) {
    from 'src/main/webapp'
    into 'build/explodedWar'
    // 使用rename函數(shù)接收 closure來修改文件名
    rename { String fileName ->
        fileName.replace('-staging-', '')
    }
    // 使用正則表達(dá)式來重命名
    rename '(.+)-staging-(.+)', '$1$2'
    rename(/(.+)-staging-(.+)/, '$1$2')
}
    //在copy過程中也可以用filter對(duì)文件內(nèi)容進(jìn)行處理
    // 分別替換文件中copyright和version的值為'2009'吊圾,'2.3.1
    // 用properties的鍵值對(duì)進(jìn)行替換
    expand(copyright: '2009', version: '2.3.1')
    expand(project.properties)
    // filter可以接受FilterReader實(shí)例類對(duì)文件內(nèi)容進(jìn)行操作
    filter(FixCrLfFilter)
    filter(ReplaceTokens, tokens: [copyright: '2009', version: '2.3.1'])
    // 使用 closure 逐行過濾處理文件內(nèi)容
    filter { String line ->
        "[$line]"
    }
    filter { String line ->
        line.startsWith('-') ? null : line
    }
    filteringCharset = 'UTF-8'

文件下載


利用插件de.undercouch.download达椰,我們可以完成文件下載的相關(guān)任務(wù),具體引入和使用方式參見:

de.undercouch.download

執(zhí)行腳本命令


通過Exec task项乒,我們讓gradle腳本來執(zhí)行命令行腳本或命令啰劲。

task stopTomcat(type:Exec) {
  // 工作目錄
  workingDir '../tomcat/bin'

  / /執(zhí)行 ./stop.sh 腳本
  commandLine './stop.sh'

  // 存儲(chǔ)命令行打印的結(jié)果
  standardOutput = new ByteArrayOutputStream()

  // 通過stopTomcat.output() 即可獲得輸出
  ext.output = {
    return standardOutput.toString()
  }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市檀何,隨后出現(xiàn)的幾起案子蝇裤,更是在濱河造成了極大的恐慌,老刑警劉巖频鉴,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栓辜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡垛孔,警方通過查閱死者的電腦和手機(jī)藕甩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來周荐,“玉大人狭莱,你說我怎么就攤上這事「抛鳎” “怎么了贩毕?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)仆嗦。 經(jīng)常有香客問我辉阶,道長(zhǎng),這世上最難降的妖魔是什么瘩扼? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任谆甜,我火速辦了婚禮,結(jié)果婚禮上集绰,老公的妹妹穿的比我還像新娘规辱。我一直安慰自己,他們只是感情好栽燕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布罕袋。 她就那樣靜靜地躺著改淑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浴讯。 梳的紋絲不亂的頭發(fā)上朵夏,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音榆纽,去河邊找鬼仰猖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奈籽,可吹牛的內(nèi)容都是我干的饥侵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼衣屏,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼躏升!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狼忱,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤膨疏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后藕赞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卖局,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年斧蜕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砚偶。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡批销,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出染坯,到底是詐尸還是另有隱情均芽,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布单鹿,位于F島的核電站掀宋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏仲锄。R本人自食惡果不足惜劲妙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望儒喊。 院中可真熱鬧镣奋,春花似錦、人聲如沸怀愧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哈垢,卻和暖如春妻柒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背温赔。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工蛤奢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陶贼。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓啤贩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拜秧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痹屹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)枉氮,斷路器志衍,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,748評(píng)論 6 342
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,510評(píng)論 25 707
  • 韶光易逝,死亡不遠(yuǎn)聊替。 以前覺得死亡離我很遠(yuǎn)很遠(yuǎn)楼肪,畢竟我才二十當(dāng)頭,正處在如花似玉的年紀(jì)惹悄〈航校回想這二十年我是多么幸運(yùn),...
    小檸檬到底萌不萌閱讀 530評(píng)論 0 0
  • 匆匆又匆匆 萬家燈火何時(shí)盡 雪入涼光就此覺 夜幕似星陽 笑語對(duì)天天嘆短 何時(shí)風(fēng)雪似萬陽 雪做雨的伴 乘風(fēng)漂流 你做...
    許梟閱讀 104評(píng)論 0 1