美文网首页
Gradle 之Groovy文件操作(二)

Gradle 之Groovy文件操作(二)

作者: PuHJ | 来源:发表于2019-04-08 10:56 被阅读0次

一、前言

java语言中提供了强大的文件操作API,利用这些系统的API和第三方的库可以直接或间接完成些复杂的文件操作。Groovy在此基础上又进行了包装,将原来的较为繁琐的文件操作又大大的简化了,其中比较突出的是XML和Json方面的转化和解析。在java中关于XML和Json用的比例比较大,XML通常用于配置系统信息,Json则用作端与端之间的通信存储格式。

下面先用一个例子看下groovy读取一个文件的:

def file = new RandomAccessFile("D:\\F\\environment\\groovy-2.4.13\\LICENSE", "rw")
// 得到该文件的Channel,
def channel = file.getChannel()

// 分配一块内存,File和Channel需直接的对ByteBuffer操作
def buffer = ByteBuffer.allocate(1024)
def bufferLen = channel.read(buffer)

while (bufferLen != -1) {
    // 写模式转变成读模式,标志位会变化
    buffer.flip()
    def len
    byte[] bytes = new byte[128]
    // buffer内存中有剩余的就循环的读
    while (len = buffer.remaining()) {
        buffer.get(bytes,0,len > 128 ? 128 : len)
        print(new String(bytes))
    }
    // 清空内存
    buffer.clear()
    // 并重新的读取Channel
    bufferLen = channel.read(buffer)
}

解释:上面的代码的类都来源于java中的NIO文件操作,这里用groovy和java混合使用读取文件夹。该操作的步骤都在代码中有说明,这里就不啰嗦了。

二、json文件

做Android开发中json是用的比较多的存储方式了。可以利用json将对象和字符串相互转换。

json转换中,可以利用第三方的库如Gson或者fastjson等,也可以用groovy自带的类。

1)、Gson

下面就用gson来演示字符串和对象之间的转换,一般做过Android的人都用过Gson库。

  • 1、build中引用Gson库
 compile 'com.google.code.gson:gson:2.6.2'

我这里使用的是Gradle,也可以用其他的依赖

  • 2、构建Student类
class Student {
    String name
    int age

    String toString() {
        "name = ${name},age = ${age}"
    }
}
  • 3、Gson操作
import com.google.gson.Gson

def gson = new Gson()

def stu = new Student(name:"phj",age: 24)

// 生成json字符串
def str = gson.toJson(stu,Student.class)
println(str)


// json字符串生成对象
def newStu = gson.fromJson(str,Student.class)
println(newStu.toString())

先初始化Gson类,使用Gson中的toJson将对象转变成json字符串,用fromJson将json字符串转变成Student对象。

Gson里面还有些高级的方法,这里就说下简单的用法,高级的我也不是特别熟练,以后用到再具体了解。

2)、groovy自带类

Groovy中也自带了对json的处理类,groovy.json.JsonSlurper,将json字符串转成实体对象,groovy.json.JsonOutput将实体对象转成json字符串。

JsonSlurper类

JsonSlurper类将字符串转化对象,在用上面的Student举个例子:

import groovy.json.JsonSlurper

def json  = '''{"age":24,"name":"phj"}'''

// json转对象
def jsonSlurper = new JsonSlurper()
def newStu = jsonSlurper.parseText(json)
println(newStu)
JsonOutput类
import groovy.json.JsonOutput

def stu = new Student(name: 'phj', age: 24)

// 对象转json
def json = JsonOutput.toJson(stu)
println json                         // 一行输出json字符串
println JsonOutput.prettyPrint(json) // 以json格式输出json字符串
  • 小结:一般使用groovy自带的类就可以完成json转化的功能,对于json字符串转变成对象,该字符串的来源可以有很多种如文件或者网络。而且数据的样式有很多并不限制与字符串文本,也可以是输入流。

三、xml文件

软件开发中,xml多用于配置文件。java中也有不同的第三方库用于解析和生成xml,而且java中的使用比较麻烦,性能也不一样。

1)XML遍历XmlSlurper

以下的文本遍历都是遍历下面的文本:

final String xml = '''
  <response version-api="2.0">
    <value>
      <books id="1" classification="android">
        <book available="20" id="1">
          <title>疯狂Android讲义</title>
          <author id="1">李刚</author>
        </book>
        <book available="14" id="2">
          <title>第一行代码</title>
          <author id="2">郭林</author>
        </book>
        <book available="13" id="3">
          <title>Android开发艺术探索</title>
          <author id="3">任玉刚</author>
        </book>
        <book available="5" id="4">
          <title>Android源码设计模式</title>
          <author id="4">何红辉</author>
        </book>
      </books>
      <books id="2" classification="web">
        <book available="10" id="1">
          <title>Vue从入门到精通</title>
          <author id="4">李刚</author>
        </book>
      </books>
    </value>
  </response>
'''
①、查找
def xmlSlurper = new XmlSlurper()
def response = xmlSlurper.parseText(xml) // 读取并解析xml数据

println response.value.books[0].book[0].title.text() // 获取标签内容
println response.value.books[0].book[0].@available   // 获取标签属性
println response.value.books[0].book[0].author.@id   // 获取标签属性

XML 的解析器是自带的XmlSlurper类,通过该类将数据解析parseText成GPathResult对象,利用该对象就可以完成节点属性等数据的查找了。

可以看到xml的查找很简单,完全符合人的顺序思维。

②、层次遍历

层次遍历就像是按照每一层的方式遍历一棵树结构一样。

def list = []
response.value.books.each { books ->
    books.book.each { book ->
        def author = book.author.text()
        if (author.equals('李刚')) {
            book.title.text()
        }
    }
}
println list.toListString()
③、深度遍历

底层是按照深度遍历图的模式

def titles = response.depthFirst().findAll { book ->
    book.author.text() == '李刚'
}
println(titles)
④、广度遍历

类似于深度遍历的一种模式

def names = response.value.books.children().findAll { node ->
    node.name() == 'book' && node.@id == '1'
}.collect { node ->
    node.title.text()
}  as List

println(names[0])

2)生成XML MarkupBuilder

def sw = new StringWriter()
// 用来生成xml数据类
def xmlBuilder = new MarkupBuilder(sw) 
// 使用伪方法创建 根结点langs,方法中是创建属性
xmlBuilder.langs(type: 'current', count: '3', mainstream: 'true'){
    // 使用伪方法创建子节点language结点,不指定key时,该value将作为标签内容
    language(flavor: 'static', version: '1.5', 'Java')
    language(flavor: 'dynamic', version: '1.6.0', 'Groovy')
    language(flavor: 'dynamic', version: '1.9', 'JavaScript')
}
println sw

生成XML的原理如上,MarkupBuilder类通过伪方法生成节点和属性、标签值。

下面通过代码自动的生成动态的XML数据:

def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)
def langs = new Langs()
xmlBuilder.langs(type: langs.type, count: langs.count, mainstream: langs.mainstream) {
    langs.languages.each { lang->
        language (flavor: lang.flavor, version: lang.version, lang.value)
    }
}


class Langs{
    String type = 'current'
    String count = '3'
    String mainstream = 'true'
    def Languages = [
            new Language(flavor: 'static', version: '1.5', value: 'java'),
            new Language(flavor: 'dynamic', version: '1.6.0', value: 'Groovy'),
            new Language(flavor: 'dynamic', version: '1.9', value: 'JavaScript')
    ]
}

class Language{
    String flavor
    String version
    String value
}

println(sw)

结果:

<langs type='current' count='3' mainstream='true'>
  <language flavor='static' version='1.5'>java</language>
  <language flavor='dynamic' version='1.6.0'>Groovy</language>
  <language flavor='dynamic' version='1.9'>JavaScript</language>
</langs>

通过遍历原有的数据结构的方式,动态的生成XML数据。

四、File文件

  • java原本的文件处理方式,输入输出流等
  • groovy扩展的方法

groovy通过闭包的方式,大大简化了文件的操作流程,如关闭流等等,但是底层还是对循环等操作的。

java的文件操作方法就不讲了,主要说下groovy特有的文件操作方式。

1)文件读取

def file = new File(''JsonTest.groovy'')
file.eachLine { line -> // 遍历文件中的每一行
  println line
}
def text = file.getText() // 返回文件中所有行内容的文本
def result = file.readLines() // 返回一个一行行文本内容的List
def readerBuffer = file.withReader { reader -> // 读取文件中前100个字符
  char[] buffer = new char[100]
  reader.read(buffer)
  return buffer
}

2)文件写入

def copy(String srcPath, String destPath) {
    try{
        // 创建目标文件
        def destFile = new File(destPath)
        if(!destFile.exists()){
            destFile.createNewFile()
        }
        // 开始拷贝
        new File(srcPath).withReader{ reader ->
            def lines = reader.readLines()
            destFile.withWriter{ writer ->
                lines.each{ line ->
                    writer.append(line+"\r\n")
                }
            }
        }
    }catch(Exception e){
        e.printStackTrace()
    }
}

3)、对象序列化

// 对象保存到文件
def saveObject(Object object, String path){
  try{
    // 创建目标文件
    def destFile = new File(path)
    if(!destFile.exists()){
      destFile.createNewFile()
    }
    destFile.withObjectOutputStream { out ->
      out.writeObject(object)
    }
  }catch(Exception e){
    e.printStackTrace()
  }
}

// 从文件读取对象
def readObject(String path){
  def obj = null
  try{
    def file = new File(path)
    if(file == null || !file.exists()) return null
    // 从文件中读取对象
    file.withObjectInputStream{ input ->
      obj = input.readObject()
    }
  }catch(Exception e){
    e.printStackTrace()
  }
  return obj
}

相关文章

网友评论

      本文标题:Gradle 之Groovy文件操作(二)

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