Gradle 使用文件


本文整理自网络,侵删。

使用文件

大多数构建工作都要使用到文件。Gradle 添加了一些概念和 API 来帮助您实现这一目标。

定位文件

你可以使用 Project.file()方法来找到一个相对于项目目录的文件 。

查找文件

build.gradle

// Using a relative path
File configFile = file('src/config.xml')
// Using an absolute path
configFile = file(configFile.absolutePath)
// Using a File object with a relative path
configFile = file(new File('src/config.xml'))  

您可以把任何对象传递给 file()方法,而它将尝试将其转换为一个绝对路径的 File 对象。通常情况下,你会传给它一个 String 或 File 的实例。而所提供的这个对象的 tostring() 方法的值会作为文件路径。如果这个路径是一个绝对路径,它会用于构构一个 File 实例。否则,会通过先计算所提供的路径相对于项目目录的相对路径来构造 File 实例。这个 file()方法也可以识别URL,例如是 file:/some/path.xml

这是把一些用户提供的值转换为一个相对路径的 File 对象的有用方法。由于 file()方法总是去计算所提供的路径相对于项目目录的路径,最好是使用 new File(somePath),因为它是一个固定的路径,而不会因为用户运行 Gradle 的具体工作目录而改变。

文件集合

一个文件集合只是表示一组文件。它通过 FileCollection 接口来表示。Gradle API 中的许多对象都实现了此接口。比如,依赖配置 就实现了 FileCollection 这一接口。

使用 Project.files()方法是获取一个 FileCollection 实例的其中一个方法。你可以向这个方法传入任意个对象,而它们会被转换为一组 File 对象。这个 Files() 方法接受任何类型的对象作为其参数。根据16.1 章节 “定位文件”里对 file() 方法的描述,它的结果会被计算为相对于项目目录的相对路径。你也可以将集合,迭代变量,map 和数组传递给 files() 方法。它们会被展开,并且内容会转换为 File 实例。

创建一个文件集合

build.gradle

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

一个文件集合是可迭代的,并且可以使用 as 操作符转换为其他类型的对象集合。您还可以使用+运算符把两个文件集合相加,或使用-运算符减去一个文件集合。这里是一些使用文件集合的例子。

使用一个文件集合

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()方法传一个闭包或一个 Callable 实例。它会在查询集合内容,并且它的返回值被转换为一组文件实例时被调用。这个闭包或 Callable 实例的返回值可以是 files() 方法所支持的任何类型的对象。这是 “实现” FileCollection 接口的简单方法。

实现一个文件集合

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 }
}  

gradle -q list 的输出结果

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

你可以向 files() 传入一些其他类型的对象:

FileCollection

它们会被展开,并且内容会被包含在文件集合内。

Task

任务的输出文件会被包含在文件集合内。

TaskOutputs

TaskOutputs 的输出文件会被包含在文件集合内。

要注意的一个地方是,一个文件集合的内容是缓计算的,它只在需要的时候才计算。这意味着您可以,比如创建一个 FileCollection 对象而里面的文件会在以后才创建,比方说在一些任务中才创建。

文件树

文件树是按层次结构排序的文件集合。例如,文件树可能表示一个目录树或 ZIP 文件的内容。它通过 FileTree 接口表示。FileTree 接口继承自 FileCollection,所以你可以用对待文件集合一样的方式来对待文件树。Gradle 中的几个对象都实现了 FileTree 接口,例如 source sets。

使用 Project.fileTree()方法是获取一个 FileTree 实例的其中一种方法。它将定义一个基目录创建 FileTree 对象,并可以选择加上一些 Ant 风格的包含与排除模式。

创建一个文件树

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*/**')  

你可以像使用一个文件集合的方式一样来使用一个文件树。你也可以使用 Ant 风格的模式来访问文件树的内容或选择一个子树:

使用文件树

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"
}  

使用归档文件的内容作为文件树

您可以使用档案的内容,如 ZIP 或者 TAR 文件,作为一个文件树。你可以通过使用 Project.zipTree() 或 Project.tarTree()方法来实现这一过程。这些方法返回一个 FileTree 实例,您可以像使用任何其他文件树或文件集合一样使用它。例如,您可以用它来通过复制内容扩大归档,或把一些档案合并到另一个归档文件中。

使用归档文件作为文件树

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 中的许多对象都有一个接受一组输入文件的属性。例如,JavaCompile 任务有一个 source 属性,定义了要编译的源代码文件。你可以使用上面所示的 files()方法所支持的任意类型的对象设置此属性。这意味着您可以通过如 File、String、集合、FileCollection 对象,或甚至是一个闭包来设置此属性。这里有一些例子:

指定一组文件

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) }
    }
}  

通常情况下,有一个与属性相同名称的方法,可以追加这个文件集合。再者,这个方法接受 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 任务来复制文件。复制任务非常灵活,并允许您进行,比如筛选要复制的文件的内容,或映射文件的名称。

若要使用 Copy 任务,您必须提供用于复制的源文件和目标目录。您还可以在复制文件的时候指定如何转换文件。你可以使用一个复制规范来做这些。一个复制规范通过 CopySpec 接口来表示。Copy 任务实现了此接口。你可以使用 CopySpec.from()方法指定源文件,使用 CopySpec.into()方法使用目标目录。

使用 copy 任务复制文件

build.gradle

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

from() 方法接受和 files() 方法一样的任何参数。当参数解析为一个目录时,该目录下的所有文件(不包含目录本身) 都会递归复制到目标目录。当参数解析为一个文件时,该文件会复制到目标目录中。当参数解析为一个不存在的文件时,参数会被忽略。如果参数是一个任务,那么任务的输出文件 (即该任务创建的文件)会被复制,并且该任务会自动添加为 Copy 任务的依赖项。into() 方法接受和 files() 方法一样的任何参数。这里是另一个示例:

示例 16.11. 指定复制任务的源文件和目标目录

阅读剩余部分

相关阅读 >>

Gradle 使用文件

Gradle 教程 - 杂七杂八

Gradle 问题反馈

Gradle 构建基础

Gradle jdepend 插件

Gradle jetty 插件

Gradle 简介

Gradle sonar runner 插件

Gradle 安装

Gradle jacoco 插件

更多相关阅读请进入《Gradle》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...