这是我参与更文挑战的第8天,活动详情查看:更文挑战
前言:
gradle构建的基本元素有project,task,和文件API project和task已经说明,这篇详情了解文件操作的api 不熟悉project和task的看这里 操作文件api还是在buildSrc插件目录中进行练习,上一篇文章已经创建好项目且准备好了插件环境
copy单个文件
在buildSrc src/main/kotlin下新建一个目录存放自定义task
我们新建一个CopyTask 继承自类型为Copy的task 注意:新建的task类必须添加Open关键字否则出错 下面异常提示class copyTask是final类型的所以我们加上open变成不为final 编译正常
在Kotlin开发中类和方法默认不允许被继承和重写,等同于Java中用 final 修饰类和方法。 如果在Kotlin 中类和方法想被继承和重写,需添加open 关键字修饰。
我们在pluginTest中注册task type类型为我们创建的copyTask
//创建一个copyFile的task
project.tasks.create("copy", CopyTask::class.java) {
copyFile()
}
下来我们开始实现copyFile的action
使用注解@TaskAction标记方法为执行Task时要运行的操作。
val from1 = "${project.rootDir}/test.txt"
val to = "${project.projectDir}"
把一个文件复制到指定的目录下面
我们在项目根路径下新建一个test.txt的文件写入hello world 并使用我们写的Task进行复制到主项目app目录下
-
利用rootDir api 定位到根目录下的test.txt
val from1 = "${project.rootDir}/test.txt"
-
使用projectDir代表app目录
val to = "${project.projectDir}"
-
开始使用api进行复制
//代表复制的源文件
from(from1)
//into代表要复制到的路径
into(to)
如果想要进行重新命名要被复制的文件名我们也可以使用gradle为我们提供的rename函数
完整代码:
open class CopyTask : Copy() {
@TaskAction
fun copyFile() {
val from1 = "${project.rootDir}/test.txt"
val to = "${project.projectDir}"
from(from1)
into(to)
//修改名字为test-copy.txt
rename {
"$it-copy.txt"
}
}
}
copy多个文件
一次copy多个文件时,我们可以把上面的例子进行扩展,根据‘copy from’api发现我们可以同时指定多参数
我们扩展上面的方法,在根目录下再创建一个test1.txt写入 'gradle copy test' 字符, 然后传入from函数中
@TaskAction
fun copyFile() {
val from1 = "${project.rootDir}/test.txt"
val from2 = "${project.rootDir}/test1.txt"
val to = "${project.projectDir}"
from(from1, from2)
into(to)
rename {
"$it-copy.txt"
}
}
执行gradlew -q copy 执行成功!
copy目录
同样使用from 和into 进行复制,我们在自定义插件中加入复制目录的action
//创建一个copyFile的task
project.tasks.create("copy", CopyTask::class.java) {
// copyFile()
copyFiles()
}
我们给from传值时就是一个目录的路径而不是单个文件路径了 我们创建一个copyTest的目录和toArc的目录 开始进行目录的复制
/**
* 复制目录
*/
@TaskAction
fun copyFiles() {
val fromSrc = "${project.rootDir}/copyTest"
val toDes = "${project.rootDir}/toArc"
from(fromSrc)
into(toDes)
}
执行gradlew -q copy发现toArc中已经多了两个文件
常用Api
有时候复制整个文件夹的时候又想进行忽略复制某种类型的文件这时候我们就需要exclude函数进行操作 我们在copyTest目录下新增加一个python.py的文件《 我们使用exclude复制时忽略掉它
- exclude()
@TaskAction
fun copyFiles() {
val fromSrc = "${project.rootDir}/copyTest"
val toDes = "${project.rootDir}/toArc"
from(fromSrc)
// 复制时忽略.py扩展的文件
exclude("*.py")
into(toDes)
}
- include()
@TaskAction
fun copyFiles() {
val fromSrc = "${project.rootDir}/copyTest"
val toDes = "${project.rootDir}/toArc"
from(fromSrc)
// 只复制以.txt为扩展的文件
include("*.txt")
// exclude("*.py")
into(toDes)
}
文件压缩、zip jar war
新建一个task type类型为Zip
注意设置压缩的路径以及压缩之后的文件名和from不同这块使用的是 AbstractArchiveTask 提供的一些属性
project.tasks.register("zip", Zip::class.java) {
archiveFileName.set("my-distribution.zip")
destinationDirectory.set(project.layout.buildDirectory.dir("dist"))
from(project.layout.buildDirectory.dir("kotlin"))
println("${project.layout.buildDirectory.dir("kotlin")}")
}
如果有想设置的属性可以对照api进行设置
public abstract class AbstractArchiveTask extends AbstractCopyTask {
// All of these field names are really long to prevent collisions with the groovy setters.
// Groovy will try to set the private fields if given the opportunity.
// This makes it much more difficult for this to happen accidentally.
private final DirectoryProperty archiveDestinationDirectory;
private final RegularFileProperty archiveFile;
private final Property<String> archiveName;
private final Property<String> archiveBaseName;
private final Property<String> archiveAppendix;
private final Property<String> archiveVersion;
private final Property<String> archiveExtension;
private final Property<String> archiveClassifier;
private final Property<Boolean> archivePreserveFileTimestamps;
private final Property<Boolean> archiveReproducibleFileOrder;