前段時間學習了一點內容,寫了一篇Groovy開發工具包。我當時就在想Kotlin怎麼沒有好用的文件操做API呢?後來我發現我太傻了,Kotlin這麼好用的語言怎麼可能沒有本身的文件API呢?html
Kotlin的IO操做都在kotlin.io包下。Kotlin的原則就是Java有的就直接利用,沒有的才本身想辦法寫。所以Kotlin的IO操做主要是依靠擴展方法,在原有的Java類上添加功能實現的。這一點卻是和Groovy有點像。java
下面介紹的不少方法都有一個Charset
參數,能夠直接要使用的字符集,默認是UTF-8。若是須要其餘的字符集,用這個參數指定就好了。正則表達式
若是學過C++的同窗可能會對Java超長的輸出語句System.out.println()
所震驚。一樣的工做在C++裏面只須要簡單的cout<<
就能夠完成。api
幸虧,在Kotlin裏面很簡單,只須要使用println
或者print
這兩個全局函數便可。咱們再也不須要冗長的前綴。數組
從終端讀取數據也很簡單,最基本的方法就是全局函數readLine
,它直接從終端讀取一行做爲字符串。若是須要更進一步的處理,可使用Kotlin提供的各類字符串處理函數來處理和轉換字符串。markdown
Kotlin爲java.io.File
提供了大量好用的擴展方法,詳細的擴展方法見這裏java.io.File。這裏我就跳着說幾個最經常使用最好用的吧。網絡
首先先看讀取文件。若是須要簡單讀取一個文件,可使用readText()
方法,它直接返回了整個文件內容。若是但願按行讀取,還可使用readLines()
方法,這會返回一個行字符串數組,咱們能夠隨意操做。若是但願直接操做字節數組,那就使用readBytes()
。若是想使用傳統的Java方式,Kotlin也能知足你。app
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。jvm
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) }
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()) }
在項目相應文件夾下咱們能夠看到下載好的圖片。