第十二章、GDK学习

  • image-20201122121731385

1、object对象

1.1、查看object对象的信息

  • /**
     * @author liangchen* @date 2020/11/22
     */
    // 使用 dump 和inspect 方法
    
    def newline = "\n"
    assert newline.toString() == "\n"
    
    // dump 对象信息
    assert newline.dump()=="<java.lang.String@a value=\n hash=10>"
    
    // 值
    assert newline.inspect() == /'\n'/
    
    
    class MyClass{
        def first = 1
        def getSecond(){
            first * 2
        }
        public third = 3
        def myMethod(){}
    }
    
    def obj = new MyClass()
    //判断是否存在某个属性
    assert  obj.hasProperty('first')
    // 判断是否存在某个方法
    assert obj.respondsTo('myMethod')
    
    // 属性的key
    def keys = ['first', 'second', 'class']
    assert obj.properties.keySet() == new HashSet<>(keys)
    
    // 属性map获取属性
    assert  1 == obj.properties['first']
    assert 1 == obj.properties.first
    
    // 调用getAt('first')
    assert 1 == obj.first
    assert 1 == obj['first']
    
    def one = 'first'
    def two = 'second'
    obj[one] = obj[two]
    // 查找存在first=2字符串
    assert obj.dump() =~'first=2'
    

1.2、Object方便使用的方法

  • 基础用法

    • package com.jack.groovy.ch12
      
      import com.jack.groovy.ch7.Address
      
      /**
       * @author liangchen* @date 2020/11/22
       */
      // 在java中,判断相等
      int a = 1;
      int b =1;
      assert  a == b
      // 在groovy中
      assert a.is(b)
      
      // switch 也不限于Integer char 类型
      switch (new Date(0)) {
          case new Date(0): println 'dates are equal'
      
      }
      
      new Date().identity {
          println "$date.$month.$year"
      }
      
      //赋值
      def address = new Address()
      address.with {
          state = '中国'
          street = '天顶乡'
      
      
      }
      
      // 格式化打印
      printf('PI=%2.5f and E = %2.5f', Math.PI, Math.E)
      
      //直接use类的静态方法
      class StringCasingCategory{
          static String lower(String string) {
              return string.toLowerCase()
          }
      }
      
      use(StringCasingCategory){
          assert "groovy" == "GROOvy".lower()
      }
      
      // sleep 打印
      text = "间断打印"
      for (c in text) {
          sleep(100)
          print c
      }
      

1.3、遍历迭代


2、文件和I/O

/**
 * @author liangchen* @date 2020/11/22
 */
file = new File('_12_1_1InteractiveObject.groovy')

file.each {println it}
assert  file.any{ it=~ /方法/}

assert 2 == file.findAll { it =~ /方法/ }.size()

assert 38== file.grep{it}.size()

2.1、遍历文件系统

  • package com.jack.groovy.ch12
    
    import groovy.io.FileType
    
    /**
     * @author liangchen* @date 2020/11/22
     */
    file = new File('.')
    // 打印文件名
    println file.name
    
    // 绝对路径
    println file.absolutePath
    
    // 规范路径
    println file.canonicalPath
    
    // 是否为目录
    println file.directory
    
    
    
    // File 遍历系统
    
    def topDir = new File('../../../../')
    def srcDir = new File(topDir,'')
    dirs = []
    srcDir.eachDir { dirs << it.name }
    assert ['com'] == dirs
    
    dirs=[]
    // 递归遍历文件夹
    topDir.eachDirRecurse {dirs << it.name}
    assert dirs.containsAll(['jack','groovy', 'ch2'])
    
    dirs = []
    // 匹配第一个
    topDir.eachDirMatch(~/[^1]*/) { dirs << it.name }
    assert dirs == ['com']
    
    // 遍历文件和目录
    files=[]
    topDir.eachFile { files << it.name }
    assert  files.contains('com')
    assert files.contains('.DS_Store')
    
    files = []
    topDir.eachFile ( FileType.FILES){files << it.name}
    assert  files.contains('.DS_Store')
    
    // 计数目录
    count = 0
    srcDir.eachFileRecurse {if(it.directory) count++}
    
    count =0
    srcDir.eachFileRecurse (FileType.DIRECTORIES) {count++}
    assert 19 == count
    topDir.eachFileMatch(~/_12_2_1.*/) { files << it.name }
    assert ['.DS_Store'] == files
    

2.2、读取输入

/**
 * @author liangchen* @date 2020/11/22
 */
example = new File("data/example.txt")

lines = ['line one', 'line two', 'line three']
assert  lines == example.readLines()

example.eachLine {
    assert it.startsWith('line')
}

hex = []
example.eachByte {hex << it}
assert  hex.size() == example.length()

example.splitEachLine(/\s/){
    assert 'line' == it[0]
}

example.withReader {reader->
    assert  'line one' == reader.readLine()
}

2.3、写出文件

  • reader 做writer

    • /**
       * 写出文件
       * @author liangchen* @date 2020/11/22
       */
      
      def outFile = new File('data/example.txt')
      def lines = ['line one', 'line two', 'line three']
      outFile.write(lines[0..1].join("\n"))
      outFile.append("\n" + lines[2])
      assert lines == outFile.readLines()
      outFile.withWriter {writer ->
          writer.writeLine(lines[0])
      }
      
      outFile.withWriterAppend ('ISO8859-1') {
          writer -> writer << lines[1] << "\n"
      
      }
      outFile << lines[2]
      
      
      TimeZone.default = TimeZone.getTimeZone("CET")
      reader = new StringReader('abc')
      writer = new StringWriter()
      
      
      writer << "\nsome String" << "\n"
      writer << [a: 1, b: 2] << "\n"
      writer << [3, 4] << "\n"
      writer << new Date(0) << "\n"
      // ready可直接做writer入参
      writer << reader << "\n"
      
      println writer.toString()
      
      
      

2.4、过滤和转换

  • new Reader / new InputStream / new DataInputStream / newDataOutputStream/new ObjectOutputStream/ new OutputStream/new Writer 获取资源

  • package com.jack.groovy.ch12
    
    /**
     * 过滤行数
     * @author liangchen* @date 2020/11/23
     */
    def n = System.lineSeparator()
    reader = new StringReader("abc")
    writer = new StringWriter()
    //当前元素的下一个元素
    reader.transformChar(writer){it.next()}
    assert  'bcd' == writer.toString()
    
    // 去掉 line字段
    reader = new File("data/example.txt").newReader()
    writer = new StringWriter()
    reader.transformLine(writer) { it - 'line' }
    assert " one${n} two${n} three${n}" == writer.toString()
    
    input = new File('data/example.txt')
    writer = new StringWriter()
    
    // 匹配有one字符串的行
    input.filterLine(writer) { it =~ /one/ }
    assert "line one${n}" == writer.toString()
    
    // 过滤长度大于8 的行数
    writer = new StringWriter()
    writer << input.filterLine {it.size() > 8}
    assert "line three${n}" == writer.toString()
    
    // base 64
    byte[] data = new byte[256]
    for(i in 0..255) {
        data[i] == i
    
    }
    store = data.encodeBase64().toString()
    // 以什么开头
    assert store.startsWith('AAECAWQFBg')
    // 以。。结尾
    assert store.endsWith  ('r7/P3+/w==')
    //解码base64
    restored = store.decodeBase64()
    assert data.toList() == restored.toList()
    

2.5、Streaming serialized objects(流序列化对象)

  • /**
     * @author liangchen* @date 2020/11/24
     */
    // 序列化
    file = new File('objects.dat')
    // 在jvm退出时候删除文件
    file.deleteOnExit()
    
    objects = [1,'Hello Groovy!', new Date()]
    // 写入对象到文件中
    file.withObjectOutputStream { outstream ->
        objects.each{
            outstream << it
        }
    }
    
    // 从文件中读取对象到retrieved中
    retrieved = []
    file.withObjectInputStream {instream ->
        instream.eachObject {
            retrieved << it
        }
    }
    
    assert  retrieved == objects
    

2.6 临时数据和文件复制

  • // 12.11 在临时目录的复制
    
    // 创建一个临时目录
    File tempDir = File.createTempDir()
    assert  tempDir.directorySize() == 0
    
    // 创建一个临时文件input.data,
    File source = new File(tempDir, 'input.dat')
    source.bytes = "hello world".bytes
    // 这个目录下所有文件大小之和
    assert tempDir.directorySize() == 11
    
    //创建一个新的文件,output.dat, 把input.dat的内容输出到output.dat中
    File destination = new File(tempDir, 'output.dat')
    destination.withDataOutputStream { os ->
        source.withDataInputStream {is ->
            os << is
        }
    }
    // 最后文件大小是 11*2 = 22
    assert  tempDir.directorySize() == 22
    // 删除临时文件夹
    tempDir.deleteDir()
    

3、线程和处理

3.1、groovy多线程

  • package com.jack.groovy.ch12
    
    
    import java.util.concurrent.BlockingQueue
    import java.util.concurrent.LinkedBlockingQueue
    
    /**
     * @author liangchen* @date 2020/11/24
     */
    // Groovy 多线程
    
    //创建线程的方式
    // 方式1
    t = new Thread(){
        // 具体运行内容
    }
    t.start()
    
    // 方式2
    Thread.start {
        //具体运行内容
    }
    Thread.start("线程名称"){
    
    }
    // 创建守护线程
    Thread.startDaemon {
        //具体运行内容
    }
    Thread.startDaemon ("线程名称"){
        // 具体运行内容
    }
    // 线程延迟1秒后运行
    current = System.currentTimeMillis()
    println "当前时间:$current"
    new Timer().runAfter(1000){
       delta = System.currentTimeMillis() - current
        println "耗时:$delta"
    }
    
    // 12.12 使用线程来解决生产者和消费者
    //在Thread中定义个静态的getName方法
    Thread.metaClass.'static'.getName = {Thread.currentThread().name}
    BlockingQueue sharedQueue = [] as LinkedBlockingQueue
    
    // 创建生产者线程
    Thread.start('push'){
        // 遍历10次
        10.times {
            try {
                println("${Thread.name}\t: ${it}")
                // 数字加到sharedQueue当中
                sharedQueue << it
                sleep(100)
            } catch (InterruptedException ignore) {}
        }
    }
    // 创建消费者线程
    Thread.start('pop') {
        for (i in 0..9) {
            sleep 200
            println("队列元素:$sharedQueue")
            println ("${Thread.name}\t : ${sharedQueue.take()}")
        }
    }
    
    

3.2、整合外部过程(执行命令行)

  • package com.jack.groovy.ch12
    
    /**
     * @author liangchen* @date 2020/11/24
     */
    //
    // 用groovy执行命令行的命令, 创建一个process, 也就是可以创建一个执行过程
    def listFiles = 'ls'.execute()
    // 这里创建一个文件夹aa
    'mkdir aa'.execute()
    def ignoreCase = "tr '[A-Z]' '[a-z]'".execute()
    def reverseSort = 'sort -r'.execute()
    println listFiles
    listFiles | ignoreCase| reverseSort
    
    reverseSort.waitForOrKill(1000)
    if (reverseSort.exitValue()) {
        println reverseSort.err.text
    }each {
        println reverseSort.text
    }
    
    // 发现list
    def outputBuffer = new StringBuffer()
    def errorBuffer = new StringBuffer()
    
    zipProcess = 'gzip -c'.execute()
    unzipProcess = 'gunzip -c'.execute()
    
    unzipProcess.consumeProcessOutput(outputBuffer,errorBuffer)
    zipProcess.consumeProcessErrorStream(errorBuffer)
    zipProcess | unzipProcess
    zipProcess.withWriter { writer->
        writer << 'Hello World'
    }
    unzipProcess.waitForOrKill(1000)
    println 'outPut:' + outputBuffer
    println 'Error:' + errorBuffer
    

4、 模板

4.1、理解模板格式

  • 模板格式
    • image-20201124195021904

4.2、模板实战

  • ${} 对应不是迭代的, <% %> 迭代情况拼接字符串

  • package com.jack.groovy.ch12
    
    import groovy.text.SimpleTemplateEngine
    
    /**
     * @author liangchen* @date 2020/11/24
     */
    //注意是三单引号  ${} 对应不是迭代的, <% %> 迭代情况拼接字符串
    mailReminder =
    '''
    Dear ${salutation?salutation+' ':''}$lastname,another month has passed and it's time for these
    <%=tasks.size()%> tasks:<% tasks.each{%>- $it<%} %>
    your collaboration is very much appreciated
    '''
    
    
    // 创建模板引擎,
    def engine = new SimpleTemplateEngine()
    // 创建模板
    def template = engine.createTemplate(mailReminder)
    // 创建绑定数据
    def binding = [
            salutation:'Mrs.',
            lastname:'Davis',
            tasks :['visit the Groovy in Action (GinA) page', 'chat with GinA readers']
    ]
    // 进行绑定
    println template.make(binding).toString()
    

4.3、高级template特性

  • 需要使用单引号,因为双引号GString在编译时候自动替换值,而模板是需要在调用绑定方法时候才替换,所有双引号会报方法找不到异常
  • StreamingTemplateEngine :处理template比较大,一般大于64000个字符
  • GStringTemplateEngine: 在写闭包中提供更好性能和扩展能力
  • XmlTemplateEngine 处理xml文件
  • MarkupTemplateEngine: 推荐使用,编译模板有更好的性能,检查在模板中使用的属性

5、Groovlets

  • 暂时不涉及

6、总结

  1. GDK 加强JDK的能力
  2. GDK使得处理I/O更加简单,自动处理资源的释放
  3. GDK使用线程也是比较简单
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值