简体   繁体   中英

Best way to use BufferedReader in Kotlin

So I've just started using Kotlin for Android, and converted my Android Java codes into Kotlin.

In one of the conversions, I stumbled upon a BufferedReader, which I would usually write in Java as the following:

String result = "";
String line = "";
BufferedReader reader = new BufferedReader(someStream);
while ( (line = reader.readLine()) != null ) {
    result += line;
}

But in Kotlin, it seems that Kotlin doesn't allow me to assign values to variables in while conditions.

Currently, I've written the code as the following:

val reader = BufferedReader(someStream)
var line : String? = ""
while (line != null) {
    line = reader.readLine()
    result += line
}

which I don't find so elegant and feels prev-gen, despite using Kotlin.

What would be the best way to use BufferedReader in Kotlin?

您可以像这样使用bufferedReader

val allText = inputStream.bufferedReader().use(BufferedReader::readText)

If you still wanted to read it line by line you could use some extension functions from std lib and do it as follows:

val reader = someStream.bufferedReader()
val iterator = reader.linesSequences().iterator()
while(iterator.hasNext()) {
    val line = iterator.next()
    // do something with line...
}
reader.close()

or alternatively, using a "functional" approach:

val reader = someStream.bufferedReader()
reader.useLines {
    it.map { line -> // do something with line }
}

by using useLines, you don't need to explicitly call close on the reader, the useLines extensions function will do it for you!

Just adding those for reference.. cheers

you can also try using the "forEachLine" method.

val file = File("./folder/test.txt")
file.bufferedReader().forEachLine {
    println("value = $it")
} 

it'll also automatically close the stream after reading the last line

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-reader/index.html

fun Reader.forEachLine(action: (String) -> Unit)
Iterates through each line of this reader, calls action for each line read and closes the Reader when it's completed.

Another way is to use a for loop:

val reader = BufferedReader(someStream)
for (line in reader.lines()) {
    println(line)
}

While is it not as concise as the accepted answer, it will allow you to loop thru and perform some kind of logic without pumping everything into one string as shown below

val allText: String = inputStream.bufferedReader().use(BufferedReader::readText)

感谢 João Gonçalves 对 stdlib 的引用,我发现如果需要,您可以使用forEachLine遍历阅读器。

use the code like this

val input = conn.inputStream
    val allText = input.bufferedReader().use(BufferedReader::readText)
    val result = StringBuilder()                   

    result.append(allText)
    return result.toString()

    } else {

    return "unsuccessful"

    }

The accepted answer fails when the stream has multiple lines. This is my solution

val allText = inputStream.bufferedReader().use { it.readLines().joinToString("") }

您可以像这样使用 BufferReader :

val data = inputStream.bufferedReader().use(BufferedReader::readText)
    

This solution includes the character \n after each line

val fileInputStream = context.openFileInput(fileName)
val reader = BufferedReader(InputStreamReader(fileInputStream))
val line = reader.buffered().use { it.readText() }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM