在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 物聯(lián)網(wǎng)/ 處理文件
快速開(kāi)始 Web 應(yīng)用
更多關(guān)于任務(wù)
編寫(xiě)構(gòu)建腳本
守護(hù)進(jìn)程
問(wèn)題解決
日志
插件
總覽
快速開(kāi)始 Java
教程-"This and That"
使用 Gradle 圖形化用戶界面
從 Gradle 使用 Ant
依賴管理的基礎(chǔ)
構(gòu)建環(huán)境
處理文件
構(gòu)建腳本的基本
使用 Gradle 命令行
快速開(kāi)始 Groovy
安裝
介紹

處理文件

大多數(shù)構(gòu)建工作都要使用到文件。Gradle 添加了一些概念和 API 來(lái)幫助您實(shí)現(xiàn)這一目標(biāo)。

定位文件

使用 Project.file() 方法來(lái)定位相對(duì)于 project 目錄相關(guān)的文件。

Example 16.1. Locating files

build.gradle

    // Using a relative path 使用相對(duì)路徑
    File configFile = file('src/config.xml')

    // Using an absolute path 使用絕對(duì)路徑
    configFile = file(configFile.absolutePath)

    // Using a File object with a relative path 使用文件對(duì)象中的相對(duì)路徑
    configFile = file(new File('src/config.xml'))

您可以把任何對(duì)象傳遞給 file() 方法,而它將嘗試將其轉(zhuǎn)換為一個(gè)絕對(duì)路徑的 File 對(duì)象。通常情況下,你會(huì)傳給它一個(gè) String 或 File 的實(shí)例。如果這個(gè)路徑是一個(gè)絕對(duì)路徑,它會(huì)用于構(gòu)構(gòu)一個(gè) File 實(shí)例。否則,會(huì)通過(guò)先計(jì)算所提供的路徑相對(duì)于項(xiàng)目目錄的相對(duì)路徑來(lái)構(gòu)造 File 實(shí)例。這個(gè) file() 方法也可以識(shí)別 URL,例如是 file:/some/path.xml。

這是把一些用戶提供的值轉(zhuǎn)換為一個(gè)相對(duì)路徑的 File 對(duì)象的有用方法。由于 file() 方法總是去計(jì)算所提供的路徑相對(duì)于項(xiàng)目目錄的路徑,最好是使用 new File(somePath),因?yàn)樗且粋€(gè)固定的路徑,而不會(huì)因?yàn)橛脩暨\(yùn)行 Gradle 的具體工作目錄而改變。

文件集合

一個(gè)文件集合簡(jiǎn)單的說(shuō)就是一組文件。它通過(guò) FileCollection 接口來(lái)表示。Gradle API 中的許多對(duì)象都實(shí)現(xiàn)了此接口。比如,15.3 依賴配置章節(jié) 就實(shí)現(xiàn)了 FileCollection 這一接口。

使用 Project.files() 方法是獲取一個(gè) FileCollection 實(shí)例的其中一個(gè)方法。你可以向這個(gè)方法傳入任意個(gè)對(duì)象,而它們會(huì)被轉(zhuǎn)換為一組 File 對(duì)象。這個(gè) files() 方法接受任何類型的對(duì)象作為其參數(shù)。根據(jù)16.1 章節(jié) “定位文件”里對(duì) file() 方法的描述,它的結(jié)果會(huì)被計(jì)算為相對(duì)于項(xiàng)目目錄的相對(duì)路徑。你也可以將集合,迭代變量,map 和數(shù)組傳遞給 files() 方法。它們會(huì)被展開(kāi),并且內(nèi)容會(huì)轉(zhuǎn)換為 File 實(shí)例。

Example 16.2. Creating a file collection

build.gradle

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

一個(gè)文件集合是可迭代的,并且可以使用 as 操作符轉(zhuǎn)換為其他類型的對(duì)象集合。您還可以使用 + 運(yùn)算符把兩個(gè)文件集合相加,或使用 - 運(yùn)算符減去一個(gè)文件集合。這里是一些使用文件集合的例子

Example 16.3. Using a file collection

build.gradle

    // Iterate over the files in the collection
    collection.each {File file ->
        println file.name
    }

    // Convert the collection to various types
    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

    // Add and subtract collections
    def union = collection + files('src/file3.txt')
    def different = collection - files('src/file3.txt')

你也可以向 files() 方法傳一個(gè)閉包或一個(gè) Callable 實(shí)例。它會(huì)在查詢集合內(nèi)容,并且它的返回值被轉(zhuǎn)換為一組文件實(shí)例時(shí)被調(diào)用。這個(gè)閉包或Callable 實(shí)例的返回值可以是 files() 方法所支持的任何類型的對(duì)象。這是 “實(shí)現(xiàn)” FileCollection 接口的簡(jiǎn)單方法。

Example 16.4. Implementing a file collection

build.gradle

    task list << {
        File srcDir

        // Create a file collection using a closure
        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 }
    }

執(zhí)行 gradle -q list

    > gradle -q list
    Contents of src
    src/dir1
    src/file1.txt
    Contents of src2
    src2/dir1
    src2/dir2

你可以向 files() 傳入一些其他類型的對(duì)象:

FileCollection

它們會(huì)被展開(kāi),并且內(nèi)容會(huì)被包含在文件集合內(nèi)。

Task

任務(wù)的輸出文件會(huì)被包含在文件集合內(nèi)。

TaskOutputs

TaskOutputs 的輸出文件會(huì)被包含在文件集合內(nèi)。

要注意的一個(gè)地方是,一個(gè)文件集合的內(nèi)容是緩計(jì)算的,它只在需要的時(shí)候才計(jì)算。這意味著您可以,比如創(chuàng)建一個(gè) FileCollection 對(duì)象而里面的文件會(huì)在以后才創(chuàng)建,比方說(shuō)在一些任務(wù)中才創(chuàng)建。

文件樹(shù)

文件樹(shù)是按層次結(jié)構(gòu)排序的文件集合。例如,文件樹(shù)可能表示一個(gè)目錄樹(shù)或 ZIP 文件的內(nèi)容。它通過(guò) FileTree 接口表示。FileTree 接口繼承自FileCollection,所以你可以用對(duì)待文件集合一樣的方式來(lái)對(duì)待文件樹(shù)。Gradle 中的幾個(gè)對(duì)象都實(shí)現(xiàn)了 FileTree 接口,例如 source sets。

使用 Project.fileTree() 方法是獲取一個(gè) FileTree 實(shí)例的其中一種方法。它將定義一個(gè)基目錄創(chuàng)建 FileTree 對(duì)象,并可以選擇加上一些 Ant 風(fēng)格的包含與排除模式

Example 16.5. Creating a file tree

build.gradle

    // Create a file tree with a base directory
    FileTree tree = fileTree(dir: 'src/main')

    // Add include and exclude patterns to the tree
    tree.include '**/*.java'
    tree.exclude '**/Abstract*'

    // Create a tree using path
    tree = fileTree('src').include('**/*.java')

    // Create a tree using closure
    tree = fileTree('src') {
        include '**/*.java'
    }

    // Create a tree using a map
    tree = fileTree(dir: 'src', include: '**/*.java')
    tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml'])
    tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**')

你可以像使用一個(gè)文件集合的方式一樣來(lái)使用一個(gè)文件樹(shù)。你也可以使用 Ant 風(fēng)格的模式來(lái)訪問(wèn)文件樹(shù)的內(nèi)容或選擇一個(gè)子樹(shù):

Example 16.6. Using a file tree

build.gradle

    // Iterate over the contents of a tree
    tree.each {File file ->
        println file
    }

    // Filter a tree
    FileTree filtered = tree.matching {
        include 'org/gradle/api/**'
    }

    // Add trees together
    FileTree sum = tree + fileTree(dir: 'src/test')

    // Visit the elements of the tree
    tree.visit {element ->
        println "$element.relativePath => $element.file"
    }

使用歸檔文件的內(nèi)容作為文件樹(shù)

您可以使用檔案的內(nèi)容,如 ZIP 或者 TAR 文件,作為一個(gè)文件樹(shù)。你可以通過(guò)使用 Project.zipTree() 或 Project.tarTree() 方法來(lái)實(shí)現(xiàn)這一過(guò)程。這些方法返回一個(gè) FileTree 實(shí)例,您可以像使用任何其他文件樹(shù)或文件集合一樣使用它。例如,您可以用它來(lái)通過(guò)復(fù)制內(nèi)容擴(kuò)大歸檔,或把一些檔案合并到另一個(gè)歸檔文件中。

Example 16.7. Using an archive as a file tree

build.gradle

    // Create a ZIP file tree using path
    FileTree zip = zipTree('someFile.zip')

    // Create a TAR file tree using path
    FileTree tar = tarTree('someFile.tar')

    //tar tree attempts to guess the compression based on the file extension
    //however if you must specify the compression explicitly you can:
    FileTree someTar = tarTree(resources.gzip('someTar.ext'))

指定一組輸入文件

Gradle 中的許多對(duì)象都有一個(gè)接受一組輸入文件的屬性。例如, JavaCompile 任務(wù)有一個(gè) source 屬性,定義了要編譯的源代碼文件。你可以使用上面所示的 files() 方法所支持的任意類型的對(duì)象設(shè)置此屬性。這意味著您可以通過(guò)如 File、String、 集合、 FileCollection對(duì)象,或甚至是一個(gè)閉包來(lái)設(shè)置此屬性。這里有一些例子:

Example 16.8. Specifying a set of files

build.gradle

    // Use a File object to specify the source directory
    compile {
        source = file('src/main/java')
    }

    // Use a String path to specify the source directory
    compile {
        source = 'src/main/java'
    }

    // Use a collection to specify multiple source directories
    compile {
        source = ['src/main/java', '../shared/java']
    }

    // Use a FileCollection (or FileTree in this case) to specify the source files
    compile {
        source = fileTree(dir: 'src/main/java').matching { include 'org/gradle/api/**' }
    }

    // Using a closure to specify the source files.
    compile {
        source = {
            // Use the contents of each zip file in the src dir
            file('src').listFiles().findAll {it.name.endsWith('.zip')}.collect { zipTree(it) }
        }
    }

通常情況下,有一個(gè)與屬性相同名稱的方法,可以追加這個(gè)文件集合。再者,這個(gè)方法接受 files() 方法所支持的任何類型的參數(shù)。

Example 16.9. Specifying a set of files

build.gradle

    compile {
        // Add some source directories use String paths
        source 'src/main/java', 'src/main/groovy'

        // Add a source directory using a File object
        source file('../shared/java')

        // Add some source directories using a closure
        source { file('src/test/').listFiles() }
    }

拷貝文件

你可以使用 Copy 任務(wù)來(lái)復(fù)制文件。復(fù)制任務(wù)非常靈活,并允許您進(jìn)行,比如篩選要復(fù)制的文件的內(nèi)容,或映射文件的名稱。

若要使用 Copy 任務(wù),您必須提供用于復(fù)制的源文件和目標(biāo)目錄。您還可以在復(fù)制文件的時(shí)候指定如何轉(zhuǎn)換文件。你可以使用一個(gè)復(fù)制規(guī)范來(lái)做這些。一個(gè)復(fù)制規(guī)范通過(guò) CopySpec 接口來(lái)表示。Copy 任務(wù)實(shí)現(xiàn)了此接口。你可以使用 CopySpec.from() 方法指定源文件,使用 CopySpec.into() 方法使用目標(biāo)目錄。

Example 16.10. Copying files using the copy task

build.gradle

    task copyTask(type: Copy) {
        from 'src/main/webapp'
        into 'build/explodedWar'
    }

from() 方法接受和 files() 方法一樣的任何參數(shù)。當(dāng)參數(shù)解析為一個(gè)目錄時(shí),該目錄下的所有文件(不包含目錄本身) 都會(huì)遞歸復(fù)制到目標(biāo)目錄。當(dāng)參數(shù)解析為一個(gè)文件時(shí),該文件會(huì)復(fù)制到目標(biāo)目錄中。當(dāng)參數(shù)解析為一個(gè)不存在的文件時(shí),參數(shù)會(huì)被忽略。如果參數(shù)是一個(gè)任務(wù),那么任務(wù)的輸出文件 (即該任務(wù)創(chuàng)建的文件)會(huì)被復(fù)制,并且該任務(wù)會(huì)自動(dòng)添加為Copy任務(wù)的依賴項(xiàng)。 into() 方法接受和 files() 方法一樣的任何參數(shù)。這里是另一個(gè)示例:

Example 16.11. Specifying copy task source files and destination directory

build.gradle

    task anotherCopyTask(type: Copy) {
        // Copy everything under src/main/webapp
        from 'src/main/webapp'
        // Copy a single file
        from 'src/staging/index.html'
        // Copy the output of a task
        from copyTask
        // Copy the output of a task using Task outputs explicitly.
        from copyTaskWithPatterns.outputs
        // Copy the contents of a Zip file
        from zipTree('src/main/assets.zip')
        // Determine the destination directory later
        into { getDestDir() }
    }

您可以使用 Ant 風(fēng)格的包含或排除模式,或使用一個(gè)閉包,來(lái)選擇要復(fù)制的文件:

Example 16.12. Selecting the files to copy

build.gradle

    task copyTaskWithPatterns(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') }
    }

此外,你也可以使用 Project.copy() 方法來(lái)復(fù)制文件。它是與任務(wù)一樣的工作方式,盡管它有一些主要的限制。首先, copy() 不能進(jìn)行增量操作(見(jiàn)"跳過(guò)處于最新?tīng)顟B(tài)的任務(wù)")。

Example 16.13. Copying files using the copy() method without up-to-date check

build.gradle

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

第二,當(dāng)一個(gè)任務(wù)用作復(fù)制源(即作為 from() 的參數(shù))的時(shí)候,copy()方法不能建立任務(wù)依賴性,因?yàn)樗且粋€(gè)方法,而不是一個(gè)任務(wù)。因此,如果您在任務(wù)的 action 里面使用 copy() 方法,必須顯式聲明所有的輸入和輸出以得到正確的行為。

Example 16.14. Copying files using the copy() method with up-to-date check

build.gradle

    task copyMethodWithExplicitDependencies{
        // up-to-date check for inputs, plus add copyTask as dependency
        inputs.file copyTask
        outputs.dir 'some-dir' // up-to-date check for outputs
        doLast{
            copy {
                // Copy the output of copyTask
                from copyTask
                into 'some-dir'
            }
        }
    }

在可能的情況下,最好是使用 Copy 任務(wù),因?yàn)樗С衷隽繕?gòu)建和任務(wù)依賴關(guān)系推理,而不需要你額外付出。copy() 方法可以作為一個(gè)任務(wù)執(zhí)行的部分來(lái)復(fù)制文件。即,這個(gè) copy() 方法旨在用于自定義任務(wù)中,需要文件復(fù)制作為其一部分功能的時(shí)候。在這種情況下,自定義任務(wù)應(yīng)充分聲明與復(fù)制操作有關(guān)的輸入/輸出。

重命名

Example 16.15. Renaming files as they are copied

build.gradle

    task rename(type: Copy) {
        from 'src/main/webapp'
        into 'build/explodedWar'
        // Use a closure to map the file name
        rename { String fileName ->
            fileName.replace('-staging-', '')
        }
        // Use a regular expression to map the file name
        rename '(.+)-staging-(.+)', '$1$2'
        rename(/(.+)-staging-(.+)/, '$1$2')
    }

過(guò)濾文件

Example 16.16. Filtering files as they are copied

build.gradle

    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'
        // Substitute property tokens in files
        expand(copyright: '2009', version: '2.3.1')
        expand(project.properties)
        // Use some of the filters provided by Ant
        filter(FixCrLfFilter)
        filter(ReplaceTokens, tokens: [copyright: '2009', version: '2.3.1'])
        // Use a closure to filter each line
        filter { String line ->
            "[$line]"
        }
    }

在源文件中,“expand” 和 “filter” 操作查找的 “token” ,被格式化成“@tokenName@” (名稱是 “tokenName”)

使用 CopySpec 類

復(fù)制規(guī)范用來(lái)組織一個(gè)層次結(jié)構(gòu)。一個(gè)復(fù)制規(guī)范繼承其目標(biāo)路徑,包含模式,排除模式,復(fù)制操作,名稱映射和過(guò)濾器。

Example 16.17. Nested copy specs

build.gradle

    task nestedSpecs(type: Copy) {
        into 'build/explodedWar'
        exclude '**/*staging*'
        from('src/dist') {
            include '**/*.html'
        }
        into('libs') {
            from configurations.runtime
        }
    }

使用 Sync 任務(wù)

Sync 任務(wù)繼承了 Copy 任務(wù)。當(dāng)它執(zhí)行時(shí),它會(huì)將源文件復(fù)制到目標(biāo)目錄中,然后從目標(biāo)目錄移除所有不是它復(fù)制的文件。這可以用來(lái)做一些事情,比如安裝你的應(yīng)用程序、 創(chuàng)建你的歸檔文件的 exploded 副本,或維護(hù)項(xiàng)目的依賴項(xiàng)的副本。

這里是一個(gè)例子,維護(hù)在 build/libs 目錄中的項(xiàng)目運(yùn)行時(shí)依賴的副本。

Example 16.18. Using the Sync task to copy dependencies

build.gradle

    task libs(type: Sync) {
        from configurations.runtime
        into "$buildDir/libs"
    }

創(chuàng)建歸檔文件

一個(gè)項(xiàng)目可以有你所想要的一樣多的 JAR 文件。您也可以將 WAR、 ZIP 和TAG 文件添加到您的項(xiàng)目。使用各種歸檔任務(wù)可以創(chuàng)建以下的歸檔文件: Zip, Tar, Jar, War, and Ear. 他們的工作方式都一樣,所以讓我們看看如何創(chuàng)建一個(gè) ZIP 文件。

Example 16.19. Creating a ZIP archive

build.gradle

    apply plugin: 'java'

    task zip(type: Zip) {
        from 'src/dist'
        into('libs') {
            from configurations.runtime
        }
    }

歸檔任務(wù)與 Copy 任務(wù)的工作方式一樣,并且實(shí)現(xiàn)了相同的 CopySpec 接口。像使用 Copy 任務(wù)一樣,你需要使用 from() 的方法指定輸入的文件,并可以選擇是否通過(guò) into() 方法指定最終在存檔中的位置。您可以通過(guò)一個(gè)復(fù)制規(guī)范來(lái)篩選文件的內(nèi)容、 重命名文件和進(jìn)行其他你可以做的事情。

歸檔文件的命名

生成的歸檔的默認(rèn)名稱是 projectName-version.type。舉個(gè)例子:

Example 16.20. Creation of ZIP archive

build.gradle

    apply plugin: 'java'

    version = 1.0

    task myZip(type: Zip) {
        from 'somedir'
    }

    println myZip.archiveName
    println relativePath(myZip.destinationDir)
    println relativePath(myZip.archivePath)

執(zhí)行 gradle -q myZip

    > gradle -q myZip
    zipProject-1.0.zip
    build/distributions
    build/distributions/zipProject-1.0.zip

它添加了一個(gè)名稱為 myZip 的 ZIP 歸檔任務(wù),產(chǎn)生 ZIP 文件 zipProject 1.0.zip 。區(qū)分歸檔任務(wù)的名稱和歸檔任務(wù)生成的歸檔文件的名稱是很重要的。歸檔的默認(rèn)名稱可以通過(guò)項(xiàng)目屬性 archivesBaseName 來(lái)更改。還可以在以后的任何時(shí)候更改歸檔文件的名稱。

這里有很多你可以在歸檔任務(wù)中設(shè)置的屬性。它們?cè)谝韵碌?a rel="nofollow" >"存檔任務(wù)-命名屬性"中列出。你可以,比方說(shuō),更改歸檔文件的名稱:

Example 16.21. Configuration of archive task - custom archive name

build.gradle

    apply plugin: 'java'
    version = 1.0

    task myZip(type: Zip) {
        from 'somedir'
        baseName = 'customName'
    }

    println myZip.archiveName

執(zhí)行 gradle -q myZip

    > gradle -q myZip
    customName-1.0.zip

您可以進(jìn)一步自定義存檔名稱:

Example 16.22. Configuration of archive task - appendix & classifier

build.gradle

    apply plugin: 'java'
    archivesBaseName = 'gradle'
    version = 1.0

    task myZip(type: Zip) {
        appendix = 'wrapper'
        classifier = 'src'
        from 'somedir'
    }

    println myZip.archiveName

執(zhí)行 gradle -q myZip

    > gradle -q myZip
    gradle-wrapper-1.0-src.zip

Table 16.1. Archive tasks - naming properties

屬性名稱 類型 默認(rèn)值 描述
archiveName String baseName-appendix-version-classifier.extension 如果這些屬性中的任何一個(gè)為空,那后面的-不會(huì)被添加到該名稱中。 生成的歸檔文件的基本文件名
archivePath File destinationDir/archiveName 生成的歸檔文件的絕對(duì)路徑。
destinationDir File 依賴于歸檔類型。JAR包和 WAR包會(huì)生成到 project.buildDir/libraries中。ZIP文件和 TAR文件會(huì)生成到project.buildDir/distributions中。 存放生成的歸檔文件的目錄
baseName String project.name 歸檔文件的名稱中的基本名稱部分。
appendix String null 歸檔文件的名稱中的附錄部分
version String project.version 歸檔文件的名稱中的版本部分。
classifier String null 歸檔文件的名稱中的分類部分。
extension String 依賴于歸檔的類型,用于TAR文件,可以是以下壓縮類型: zip, jar, war, tar, tgz or tbz2. 歸檔文件的名稱中的擴(kuò)展名稱部分。

共享多個(gè)歸檔之間的內(nèi)容

你可以使用Project.copySpec()方法在歸檔之間共享內(nèi)容。