Kotlin学习(9)文件I/O、正则表达式与多线程

网友投稿 278 2022-09-21

Kotlin学习(9)文件I/O、正则表达式与多线程

1. 文件I/O操作

1.1 读文件

readText:获取文件全部内容字符串如果想要简单的读取文件内容,则使用 readText(),可以返回整个文件内容

fun getFileContent(filename: String): String{ val f = File(filename) return f.readText(Charset.forName("UTF-8"))}

readLines:获取文件每行内容如果想要获取每行的内容,我们可以使用 split("\n")来获得一个每行内容的数组。我们也可以直接调用Kotlin封装好的readLines(),获取每行的内容:

fun getFileLines(filename: String): List { return File(filename).readLines(Charset.forName("UTF-8"))}

readBytes():读取字节流数组

//返回这个文件的字节数组val bytes: ByteArray = f.readBytes()println(bytes.joinToString(separator = " "))//与Java互操作,直接调用Java中的InputStreamval reader: Read = f.reader()val inputStream: InputStream = f.inputStream()val bufferedReader: BufferedReader = f.bufferedReader()

bufferedReader:获取文件的方法签名

fun File.bufferedReader( charset: Charset = Charsets.UTF_8 bufferSize: Int = DEFAULT_BUFFER_SIZE):

1.2 写文件 使用Kotlin扩展的函数,写入文件也变得相当简单。我们可以写入字符串,也可以写入字节流,还可以直接调用Java的Writer或者OutputStream类,写文件通常分为​​​覆盖写​​​和​​追加写​​两种。

writeText:覆盖写文件我们使用​​​writeText()​​直接向一个文件中写入字符串text的内容

fun writeFile(text: String, destFile: String) { val f = File(destFile) if(!f.exists()){ f.createNewFile() } //覆盖写入文件内容 f.writeText(text, Charset.defaultCharset())}

appendFile: 末尾追加写文件使用​​​appendFile()​​ 向一个文件的末尾追加写入内容text

//追加文件内容fun appendFile(text: String, destFile: String){ val f = File(destFile) if(!f.exists()){ f.createNewFile() } f.appendText(text, Charset.defaultCharset())}

appendBytes: 追加写入字节数组追加字节数组到该文件的末尾追加写入内容text

fun File.appendBytes(array: ByteArray)

bufferedWriter: 获取缓存区写对象获取改文件的bufferedWrite()方法签名

fun File.bufferedWriter( charset: Charset = charsets.UTF-8 bufferSize: Int = DEFAULT_BUFFER_SIZE):

1.3 遍历文件树

walk:遍历文件树

fun traverseFileTree(filename: String) { val f = File(filename) val fileTreeWalk = f.walk() //遍历文件夹下面的所有文件的路径 fileTreeWalk.iterator().forEach{ println(it.absolutePath) }}//遍历当前文件下所有的子目录文件,并将结果存入到一个 Iterator中fun getFileIterator(filename: String): Iterator { val f = File(filename) val fileTreeWalk = f.walk() return fileTreeWalk.iterator()}//我们遍历当前文件夹下的所有目录,还可以根据条件进行过滤fun getFileSequenceBy(filename: String, p: (File) -> Boolean): Sequuence { val f = File(filename) //根据条件p过滤 return f.walk().fileter(p)}

copyRecursively :递归复制文件复制改文件或者递归复制该目录及其所有子文件到指定路径下, 如果指定路径下的文件不存在,会自动创建。

fun File.copyRecursiverly( target: File, //目标文件 overwrite: Boolean = false, //是否覆盖。true:覆盖之前先删除原来的文件 onError: (File, IOException) -> OnErrorAction = { _, exception -> throw exception } //错误处理)

2. 网络I/O

根据URL获取该URL响应HTML函数:

fun getUrlContent(url: String): String{ //获取该URL的响应HTML文本 return URL(url).readText(Charset.defaultCharset())}

根据URL获取该URL响应比特数组函数:

fun getUrlBytes(url: String): ByteArray{ return URL(url).readBytes()}

把URL响应字节数组写入文件中:

fun writeUrlBytesTo(filename: String, url: String){ val bytes = URL(url).readBytes() File(filename).writeBytes(bytes)}

3. 执行Shell命令

在Groovy语言中,我们可以用Shell命令来执行I/O操作 首先我们来扩展 String的 ​​​execute()​​,让这个函数来实现Shell命令

//给String扩展 execute()函数fun String.execute(): Process { val runtime = Runtime.getRuntime() return runtime.exec(this) }//然后给Process类扩展一个 text() 函数fun Process.text(): String { var output = "" val inputStream = this.inputStream val isr = InputStreamReader(inputStream) var reader = BufferedReader(isr) var line: String? = "" while (line != null) { line = reader.readLine() output += line + "\n" } return output}

完成了上面两个简单函数的扩展后,就可以在下面的代码上测试 Shell命令:

val p = "ls".execute()val exitCode = p.waitFor()val text = p.text()println(exitCode)println(text)

4. 正则表达式

我们在Kotlin中除了仍然可以使用 Java中的 Pattern、Matcher等类之外,Kotlin还提供了一个正则表达式类 kotlin\text\regex\Regex.kt,我们通过 Regex的构造函数来创建一个正则表达式。

4.1 构造Regex表达式 使用Regex构造函数如下:

//创建一个Regex对象,匹配的正则表达式是 [a-z]+val r1 = Regex("[a-z]+") //RegexOption 是直接使用的Java类Pattern中的正则匹配选项val r2 = Regex("[a-z]+", RegexOption.IGNORE_CASE)

RegexOption 是直接使用的Java类Pattern中的正则匹配选项 使用String的 toRegex() 如下:

//直接使用Kotlin中给String扩展的toRegex函数val r3 = "[A-Z]+".toRegex()

4.2 Regex函数

matches()如果输入的字符串全部匹配正则表达式则返回 true,否则返回false

val r1 = Regex("[a-z]+")>>>r1.matches("ABCzxc") //其中大写的ABC不匹配,则返回false>falseval r2 = Regex("[a-z]+",RegexOption.IGNORE_CASE) //正则表达式,忽略大小>>>r2.matches("ABCzxc")>truevalr r3 = [A-Z]+".toRegex()>>>r3.matches("123123")>false

containsMatchIn()如果输入字符串中至少有一个匹配就返回 true,如果没有匹配就返回false

val r1 = Regex("[0-9]+")>>>r1.containsMatchIn("012AAAE")>true>>>r1.containsMatchIn("asdad")>false

matchEntire()如果输入的字符串全部匹配,则返回一个MacherMatchResult,否则返回null

val r1 = Regex("[0-9]+")>>>r1.matchEntire("1234567890") //全部满足条件>kotlin.text.MacherMatchResult@xxxxxx>>>r1.matchEntire("1234567890!")>null//我们可以访问MatcherMatchResult的value属性来获得匹配的值//其中的使用了安全调用符,表明可以返回空值>>>r1.matchEntire("1234567890")?.value>1234567890

replace(input: CharSequence, replacement: String): String把输入的字符串中匹配的内容替换成 replacement的内容

val r1 = Regex("[0-9]+")>>>r1.replace("12345XYZ","abcd")//12345将被替换成abcd>abcdXYZ

replace(input: CharSequence, transform:(MatchResult) -> CharSequence): Stringreplace()的功能是把输入的字符串中匹配到的值,用函数​​​transform()​​ 映射之后的新值进行替换

val r1 = Regex("[0-9]+")>>>r1.replace("1zxc2",{ (it.value.toInt() * it.value.toInt()).toString() })//匹配到的数字开平方>1zxc4

find()函数会返回第一个匹配的MatcherMatchResult对象。

val r1 = Regex("[0-9]+")>>>r1.find("12314rsfiafp123asookf1`1")?.value()>12314

findAll()返回所有匹配的MatcherMatchResult序列。

val r1 = Regex("[0-9]+")val sequence = r1.findAll("123abc456def789gh")>>>sequence>kotlin.sequences.GeneratorSequence@xxxxx>>>sequence.forEach{println(it.value)}>123>456>789

4.3 使用Java的正则表达式 在Kotlin中仍然可以使用Java正则表达式的API

val r1 = Regex("[0-9]+")val p = r1.toPattern()val m = p.matcher("123abc456")while (m.find()) { val d = m.group() println(d)}>123>456

5. 多线程编程

5.1 创建线程 因为我们可以在Kotlin中使用Java的类,所以我们可以使用Java的方式创建一个线程:

用对象表达式创建一个线程

//用对象表达式创建一个线程//object表达式object : Thread() { override fun run() { sleep(1000) println("Hello") } }.start()

使用Lambda表达式下面是如何将一个​​​Runnable​​传递给一个新创建的Thread实例:

Thread { Thread.sleep(1000) println("hi")}.start()

使用Kotlin封装的Thread()函数

//kotlin中的线程操作thread(start = true, isDaemon = false, name = "HiThread", priority = 4) { sleep(1000) println("hi")}

@Synchronized fun appendFile(text: String, filename: String) { val f = File(filename) if (!f.exists()) { f.createNewFile() } f.appendText(text, Charset.defaultCharset()) }

所以注解 ​​@Synchronized​​​和Java中的 ​​synchronized​​​有着一样的效果 对于同步块,我们使用synchronized函数,它使用锁作为参数:

fun appendFileSync(text: String, filename: String) { val f = File(filename) if (!f.exists()) { f.createNewFile() } synchronized(this) { f.appendText(text, Charset.defaultCharset()) } }

5.3 可变字段 同样地,Kotlin中没有 volatile关键字,但是有 ​​​@Volatile​​ 注解

@Volatile var running = false fun start() { running = true thread(start = true) { while (running) { println("Start") } } } fun stop(){ running = false; println("Stop") }

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Android 屏蔽系统设置字号
下一篇:微信等多家APP被点名!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~