美文网首页
Gradle第10课:Gradle 中文件的实战操作

Gradle第10课:Gradle 中文件的实战操作

作者: 米饭超人 | 来源:发表于2018-08-28 11:09 被阅读31次

    需要准备

    • 一个熟悉的 IDE 开发工具
    • JDK 7及以上
    • Gradle 3.2以上

    几种基础的文件操作类型

    • 本地文件
    • 文件集合
    • 文件树
    • 文件拷贝
    • 归档文件

    各种文件操作类型的详细介绍

    1.本地文件

    使用Project.file(java.lang.Object)方法,通过指定文件的相对路径或绝对路径来对文件的操作,其中相对路径为相对工程项目的目录,而不是当前工作空间的目录,因为当前工作空间目录会随用户执行 Gradle 脚本的方式不同而变化。

    其实使用Project.file(java.lang.Object)方法创建的 File 对象就是 Java 中的 File 对象,我们可以使用它就像在 Java 中使用一样。示例代码如下:

    // 使用相对路径
    File configFile = file('src/config.xml')
    configFile.createNewFile();
    
    // 使用绝对路径
    configFile = file(‘/Users/bill/HelloWorld/src/config.xml’)
    println(configFile.absolutePath)
    
    // 使用一个文件对象
    configFile = file(new File('src/config.xml'))
    println(configFile.exists())
    

    我们在控制台执行命令gradle tasks来查看结果,可以看到在项目的 src 目录下创建了一个 config.xml 文件,同时在控制台打印输出了如下信息:

    $ gradle tasks
    /Users/bill/HelloWorld/src/config.xml
    true
    

    2.文件集合

    文件集合就是一组文件的列表,在 Gradle 中,文件集合用 FileCollection 接口表示。我们可以使用Project.files(java.lang.Object[])方法来获得一个文件集合对象,如下代码创建一个 FileCollection 实例:

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

    注意:文件集合中的文件对象都是延迟操作的,也就是说你可以创建一个 FileCollection 对象,它所包含的所有文件都是在未来被其它任务调用时才会真正的创建。

    3.文件树

    文件树是有层级结构的文件集合,一个文件树它可以代表一个目录结构或一 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"
    }
    

    4.文件拷贝

    我们可以使用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
        }
    }
    

    5.归档文件

    通常一个项目会有很多的 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 对文件的具体操作方法,这里主要介绍了本地文件、文件集合、文件树、文件拷贝和归档文件。

    相关文章

      网友评论

          本文标题:Gradle第10课:Gradle 中文件的实战操作

          本文链接:https://www.haomeiwen.com/subject/jfdfwftx.html