gradle系列——gradle操作文件详解

我们的疲劳通常不是由于工作,而是由于忧虑,紧张和不快

——戴尔·卡耐基

我们在Android开发中经常会进行文件相关的操作,我们对gradle文件操作做一个说明,以便于将来见到这些命令知道是干啥的

本地文件

gradle中操作本地文件使用的是 Project.file(java.lang.Object)方法, 通过指定文件的相对路径或者绝对路径来进行操作,相对路径指的是项目的相对路径,而不是当前文件的相对路径。

示例代码如下:

// 使用相对路径
File configFile = file('src/test.xml')
configFile.createNewFile();

// 使用绝对路径
configFile = file(/Users/dds/HelloWorld/src/test.xml’)
println(configFile.absolutePath)

// 使用一个文件对象
configFile = file(new File('src/test.xml'))
// 打印文件是否存在
println(configFile.exists())

我们在控制台执行命令gradle tasks来查看结果

$ gradle tasks
/Users/dds/HelloWorld/src/test.xml
true

文件集合

Gradle中文件集合就是类似于java中的数组,Gradle中使用FileCollection接口表示, 可以使用Project.files(java.lang.Object[])方法来获得一个文件集合对象 , 所有文件集合都是用到的时候才会创建

如下代码 :

FileCollection collection = files('src/test1.txt',
        new File('src/test2.txt'),
        ['src/test3.txt', 'src/test4.txt'])

遍历操作如下

// 遍历所有集合
collection.each { File file ->
    println file.name
}

转换操作如下

// 把文件集合转换为Set类型
Set set1 = collection.files
Set set2 = collection as Set
// 把文件集合转换为List类型
List list = collection as List
// 把文件集合转换为String类型
String path = collection.asPath
// 把文件集合转换为File类型
File file1 = collection.singleFile
File file2 = collection as File

增加或者删除操作

// 添加或者删除一个集合
def union = collection + files('src/test5.txt')
def different = collection - files('src/test3.txt')

文件树

文件树是有层级结构的文件集合,一个文件树它可以代表一个目录结构或一 ZIP 压缩包中的内容结构。文件树是从文件集合继承过来的,所以文件树具有文件集合所有的功能。

我们可以使用Project.fileTree(java.util.Map)方法来创建文件树对象,还可以使用过虑条件来包含或排除相关文件。示例代码如下:

// 指定目录创建文件树对象
FileTree tree = fileTree(dir: 'src/main')

// 给文件树对象添加包含指定文件
tree.include '**/*.java'
// 给文件树对象添加排除指定文件
tree.exclude '**/Abstract*'

// 使用路径创建文件树对象,同时指定包含的文件
tree = fileTree('src').include('**/*.java')

// 通过闭包创建文件树
tree = fileTree('src') {
    include '**/*.java'
}

// 通过map创建文件树
tree = fileTree(dir: 'src', include: '**/*.java')
tree = fileTree(dir: 'src', includes: ['**/*.java', '**/*.xml'])
tree = fileTree(dir: 'src', include: '**/*.java', exclude: '**/*test*/**')

下面示例展示了文件树的相关操作:

// 遍历文件树的所有文件
tree.each {File file ->
    println file
}

// 过虑生成新的文件树对象
FileTree filtered = tree.matching {
    include 'org/gradle/api/**'
}

// 使用“+”号合并两个文件树,同文件集合的“+”操作一样
FileTree sum = tree + fileTree(dir: 'src/test')

// 访问文件树中各项内容
tree.visit {element ->
    println "$element.relativePath => $element.file"
}

文件拷贝

我们可以使用Copy任务来拷贝文件,通过它可以过虑指定拷贝内容,还能对文件进行重命名操作等。Copy任务必须指定一组需要拷贝的文件和拷贝到的目录,这里使用CopySpec.from(java.lang.Object[])方法指定原文件;使用CopySpec.into(java.lang.Object)方法指定目标目录。示例代码如下:

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

from()方法接受的参数和文件集合时files()一样。当参数为一个目录时,该目录下所有的文件都会被拷贝到指定目录下(目录自身不会被拷贝);当参数为一个文件时,该文件会被拷贝到指定目录;如果参数指定的文件不存在,就会被忽略;当参数为一个 Zip 压缩文件,该压缩文件的内容会被拷贝到指定目录。

into()方法接受的参数与本地文件时file()一样。 示例代码如下:

task copyTask(type: Copy) {
    // 拷贝src/main/webapp目录下所有的文件
    from 'src/main/webapp'
    // 拷贝单独的一个文件
    from 'src/staging/index.html'
    // 从Zip压缩文件中拷贝内容
    from zipTree('src/main/assets.zip')
    // 拷贝到的目标目录
    into 'build/explodedWar'
}

在拷贝文件的时候还可以添加过虑条件来指定包含或排除的文件,示例如下:

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

在拷贝文件的时候还可以对文件进行重命名操作,示例如下:

task rename(type: Copy) {
    from 'src/main/webapp'
    into 'build/explodedWar'
    // 使用一个闭包方式重命名文件
    rename { String fileName ->
        fileName.replace('-staging-', '')
    }
    // 使用正则表达示来映射文件名
    rename '(.+)-staging-(.+)', '$1$2'
    rename(/(.+)-staging-(.+)/, '$1$2')
}

在上面的例子中我们都是使用Copy任务来完成拷贝功能的,那么有没有另外一种方式呢?答案是肯定的,那就是Project.copy(org.gradle.api.Action)方法。下面示例展示了copy()方法的使用方式:

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

接下来我们再看一种同步拷贝的方式。什么是同步拷贝呢?就是在拷贝的时候,把原文件拷贝到目标目录时,会把目标目录下之前的全部清除,这种方式很适合项目的依赖库拷贝。示例代码如下:

task libs(type: Sync) {
    from configurations.runtime
    // 拷贝之前会把$buildDir/libs目录下所有的清除
    into "$buildDir/libs"
}

最后介绍一种很常用也很特别的拷贝方式:嵌套形式的拷贝。

task nestedSpecs(type: Copy) {
    into 'build/explodedWar'
    exclude '**/*staging*'
    from('src/dist') {
        include '**/*.html'
    }
    // 将运行时的依赖库拷贝到libs目录下
    into('libs') {
        from configurations.runtime
    }
}

归档文件

通常一个项目会有很多的 Jar 包,我们希望把项目打包成一个 WAR,ZIP 或 TAR 包进行发布,这时我们就可以使用ZipTarJarWarEar任务来实现,不过它们的用法都一样,所以在这里我只介绍Zip任务的示例。

首先,创建一个 Zip 压缩文件,如下代码所示:

apply plugin: 'java'

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

其次,可以指定生成的 Zip 压缩文件名称,示例如下:

apply plugin: 'java'
version = 1.0

task myZip(type: Zip) {
    from 'src/dist'
    baseName = 'myGame'
}

println myZip.archiveName

执行命令gradle -q myZip,输出结果为:

> gradle -q myZip
myGame-1.0.zip

最后,我们可以使用Project.zipTree(java.lang.Object)Project.tarTree(java.lang.Object)方法来创建访问 Zip 压缩包的文件树对象,示例代码如下:

// 使用zipTree
FileTree zip = zipTree('someFile.zip')
// 使用tarTree
FileTree tar = tarTree('someFile.tar')

参考链接

Gradle相关系列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ddssingsong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值