前段時間學習了一點內容,寫了一篇Groovy開發工具包。我當時就在想Kotlin怎么沒有好用的文件操作API呢?后來我發現我太傻了,Kotlin這么好用的語言怎么可能沒有自己的文件API呢?
Kotlin的IO操作都在kotlin.io包下。Kotlin的原則就是Java有的就直接利用,沒有的才自己想辦法寫。因此Kotlin的IO操作主要是依靠擴展方法,在原有的Java類上添加功能實現的。這一點倒是和Groovy有點像。
下面介紹的很多方法都有一個Charset參數,可以直接要使用的字符集,默認是UTF-8。如果需要其他的字符集,用這個參數指定就行了。
終端IO
如果學過C++的同學可能會對Java超長的輸出語句System.out.println()所震驚。同樣的工作在C++里面只需要簡單的cout<<就可以完成。
幸好,在Kotlin里面很簡單,只需要使用println或者print這兩個全局函數即可。我們不再需要冗長的前綴。
從終端讀取數據也很簡單,最基本的方法就是全局函數readLine,它直接從終端讀取一行作為字符串。如果需要更進一步的處理,可以使用Kotlin提供的各種字符串處理函數來處理和轉換字符串。
文件IO
Kotlin為java.io.File提供了大量好用的擴展方法,詳細的擴展方法見這里java.io.File。這里我就跳着說幾個最常用最好用的吧。
首先先看讀取文件。如果需要簡單讀取一個文件,可以使用readText()方法,它直接返回了整個文件內容。如果希望按行讀取,還可以使用readLines()方法,這會返回一個行字符串數組,我們可以隨意操作。如果希望直接操作字節數組,那就使用readBytes()。如果想使用傳統的Java方式,Kotlin也能滿足你。
fun readFile() {
val filename = """C:\Windows\System32\drivers\etc\hosts"""
val file = File(filename)
val contents = file.readText()
println(contents)
//大寫前三行
file.readLines().take(3).forEach {
println(it.toUpperCase())
}
//直接處理行
file.forEachLine(action = ::println)
//讀取為bytes
val bytes: ByteArray = file.readBytes()
println(bytes.joinToString(separator = ""))
//直接處理Reader或InputStream
val reader: Reader = file.reader()
val inputStream: InputStream = file.inputStream()
val bufferedReader: BufferedReader = file.bufferedReader()
}
和讀取文件類似,寫入文件也很簡單。我們可以寫入字符串,也可以寫入字節流。還可以直接使用Java的Writer或者OutputStream。
fun writeFile() {
val currentDir = System.getProperty("user.dir") + "\\out"
val file = File(currentDir, "hehe.txt")
file.writeText("呵呵呵哈哈哈")
println(file.readText())
file.writeBytes(byteArrayOf(12, 56, 83, 57))
println(file.readText())
//追加方式寫入字節或字符
file.appendBytes(byteArrayOf(93, 85, 74, 93))
file.appendText("吼啊")
println(file.readText())
//直接使用writer和outputstream
val writer: Writer = file.writer()
val outputStream: OutputStream = file.outputStream()
val printWriter: PrintWriter = file.printWriter()
遍歷文件樹
和Groovy一樣,Kotlin也提供了方便的功能來遍歷文件樹。遍歷文件樹需要調用擴展方法walk()。它會返回一個FileTreeWalk對象,它有一些方法用於設置遍歷方向和深度,詳情參見FileTreeWalk。
下面的例子遍歷了指定文件夾下的所有可執行文件。
fun traverseFileTree() {
val systemDir = File("""C:\Windows""")
val fileTree: FileTreeWalk = systemDir.walk()
fileTree.maxDepth(1)
.filter { it.isFile }
.filter { it.extension == "exe" }
.forEach(::println)
}
網絡IO
Kotlin為java.NET.URL增加了兩個擴展方法,readBytes和readText。我們可以方便的使用這兩個方法配合正則表達式實現網絡爬蟲的功能。
下面第一個例子簡單的獲取了百度首頁的源代碼。第二個例子先獲取了必應首頁圖片的XML格式信息,然后通過正則表達式和分組獲取圖片的相對URL並組合出實際URL,然后調用readBytes()方法讀取到字節流並寫入文件。
fun readFromNet() {
//返回百度首頁
val baidu = URL("http://www.baidu.com")
val contents = baidu.readText()
//println(contents)
//獲取必應首頁圖片並保存
//獲取XML格式圖片信息
val bing = URL("http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1&mkt=en-US")
val texts = bing.readText()
//獲取url地址和文件名
val regex = Regex("""<url>(.*)</url>""")
val result = regex.find(texts)
val imageUrl = "http://www.bing.com" + result!!.groupValues[1]
val filename = imageUrl.substring(imageUrl.lastIndexOf('/'))
//寫入文件
val output = File(System.getProperty("user.dir") + "\\out", filename)
val requestUrl = URL(imageUrl)
output.writeBytes(requestUrl.readBytes())
}
在項目相應文件夾下我們可以看到下載好的圖片。

- 頂
- 0
