您的位置:首页 > 移动开发 > Android开发

Android Gradle学习记录3 Groovy处理文件

2017-07-08 16:44 597 查看
这篇博客记录一下Groovy处理文件时涉及的基本操作。

整体来说,Groovy的I/O操作是建立在Java的I/O操作之上的,

不过进行了更为简单的封装,并且利用Closure来简化代码的编写。

1 读文件

Groovy读取文件时,与Java一致,首先需要创建文件对应的对象,

对应的操作类似于:

def targetFile = new File("/home/zhangjian/Desktop/file.txt")


1.1 读取文件的每一行

创建出文件对应的对象后,可以直接利用eachLine接口读取文件的每一行。

eachLine接口的参数为一个Closure,类似的用法类似于:

targetFile.eachLine { String oneLine ->
println oneLine
}


1.2 得到文件的全部内容

如果需要直接得到文件中的全部内容,可以利用文件对象的getBytes接口:

//该接口返回的是文件内容对应的byte[]
def bytes = targetFile.getBytes()
//与上述接口对应,还可以直接使用targetFile.bytes这个属性获取文件内容


1.3 获取文件对应的inputStream

与Java一样,Groovy中的文件也可以利用inputStream来进行操作,

对应的操作类似于:

//实际上获取的是Java中的BufferedInputStream
def ism = targetFile.newInputStream()
//利用inputStream的接口进行相关操作
println ism.readLines()
//使用完毕后同样需要关闭
ism.close()


当然,Groovy中的file对象有一个withInputStream接口,可以接受一个Closure对象作为参数。

在接口中可以仅关注inputStream的相关的操作,不用负责关闭inputStream。

类似的操作类似于:

targetFile.withInputStream { ism ->
println ism.readLines()
}


2 写文件

与读文件类似,Groovy同样可以利用Java中outputStream来进行写文件相关的操作。

类似的操作如下:

//这里获取的实际是Java中的BufferedOutputStream
def osm = targetFile.newOutputStream()
osm.write("just a test".getBytes())
osm.close()


同样,file对象同样有一个withOutputStream接口,可以简化outputStream相关的操作:

targetFile.withOutputStream {  osm ->
osm.write("just a new test".getBytes())
}


最后,Groovy中的outputStream重载了<<操作符,

可以比较方便地完成文件的复制,对应的操作类似于:

def srcFile = new File("/home/zhangjian/Desktop/file.txt")
def dstFile = new File("/home/zhangjian/Desktop/dst.txt")

dstFile.withOutputStream {  osm ->
srcFile.withInputStream {  ism ->
//直接将inputStream中读取到的内容写入到outputStream
osm << ism
}
}


3 XML操作

Groovy中解析XML文件的操作比较直观,主要用到了GPathResult对象。

我们通过一个例子,很容易明白它的用法。

我们以Android中应用stk为例,看看Groovy如何解析其对应的AndroidManifest.xml。

xml文件的内容如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 http://www.apache.org/licenses/LICENSE-2.0 
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="com.android.stk"
android:sharedUserId="android.uid.phone">

<original-package android:name="com.android.stk" />

<protected-broadcast android:name="com.android.stk.DIALOG_ALARM_TIMEOUT" />

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.RECEIVE_STK_COMMANDS" />

<application android:icon="@drawable/ic_launcher_sim_toolkit"
android:label="@string/app_name"
android:clearTaskOnLaunch="true"
android:process="com.android.phone"
android:taskAffinity="android.task.stk"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">

<activity android:name="StkMain"
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/app_name"
android:enabled="false"
android:exported="true"
android:taskAffinity="android.task.stk.StkLauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name="StkLauncherActivity"
android:theme="@android:style/Theme.Material.Light"
android:label="@string/app_name"
android:exported="false"
android:taskAffinity="android.task.stk.StkLauncherActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity android:name="StkMenuActivity"
android:theme="@android:style/Theme.Material.Light"
android:icon="@drawable/ic_launcher_sim_toolkit"
android:label="@string/app_name"
android:configChanges="orientation|locale|screenSize|keyboardHidden|mnc|mcc"
android:exported="false"
android:taskAffinity="android.task.stk.StkLauncherActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity android:name="StkInputActivity"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher_sim_toolkit"
android:theme="@android:style/Theme.Material.Light"
android:configChanges="orientation|locale|screenSize|keyboardHidden"
android:exported="false"
android:taskAffinity="android.task.stk.StkLauncherActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="StkDialogActivity"
android:configChanges="orientation|locale|screenSize|keyboardHidden"
android:theme="@android:style/Theme.Material.Light"
android:exported="false"
android:taskAffinity="android.task.stk.StkLauncherActivity">
</activity>

<activity android:name="ToneDialog"
android:exported="false"
android:theme="@android:style/Theme.Material.Light"
android:taskAffinity="android.task.stk.StkLauncherActivity">
</activity>

<receiver android:name="com.android.stk.StkCmdReceiver">
<intent-filter>
<action android:name= "android.intent.action.stk.command" />
<action android:name= "android.intent.action.stk.session_end" />
<action android:name= "android.intent.action.stk.icc_status_change" />
<action android:name= "android.intent.action.stk.alpha_notify" />
<action android:name= "android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>

<receiver android:name="com.android.stk.BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_INITIALIZE" />
</intent-filter>
</receiver>

<service android:name="StkAppService" />

</application>
</manifest>


我们看看对应的Groovy脚本:

//必须导入这个包
import groovy.util.slurpersupport.GPathResult

//定义文件
def srcFile = new File("/home/zhangjian/Desktop/AndroidManifest.xml")

//定义对应的解析器
def xmlParser = new XmlSlurper()

//得到解析结果GPathResult
GPathResult gpathResult=xmlParser.parse(srcFile)

//GPathResult对应的其实就是整个Xml文件的根元素,即manifest
//获取某个属性的值时,利用@加上属性名即可
println gpathResult.@'package'

//所有的子节点都是上一级节点的成员
//这里就是打印manifest中所有uses-permission的值
//注意这里包含符号-, 必须用''包裹属性
for (permission in gpathResult.'uses-permission') {
println permission.@'android:name'
}

//打印application的属性
println gpathResult.application.@'android:icon'

//activity是application的子节点
for (activity in gpathResult.application.activity) {
println activity.@'android:name'
}

//receiver也是application的子节点
for (receiver in gpathResult.application.receiver) {
println receiver.@'android:name'
}


我们看一看打印结果:

com.android.stk
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.GET_TASKS
android.permission.RECEIVE_STK_COMMANDS
@drawable/ic_launcher_sim_toolkit
StkMain
StkLauncherActivity
StkMenuActivity
StkInputActivity
StkDialogActivity
ToneDialog
com.android.stk.StkCmdReceiver
com.android.stk.BootCompletedReceiver


通过比对xml文件和结果,应该不难看出上面Groovy脚本的含义,

同时也比较容易理解GPathResult解析xml后包含内容的组织形式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: