Лучший способ использования BufferedReader в Котлине

Поэтому я только начал использовать Kotlin для Android и конвертировал свои коды Android в Kotlin.

В одном из преобразований я наткнулся на BufferedReader, который я обычно пишу на Java следующим образом:

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

Но в Котлине кажется, что Котлин не позволяет мне присваивать значения переменным в условиях.

В настоящее время я написал код следующим образом:

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

который я не нахожу настолько элегантным и чувством предчувствия, несмотря на использование Котлина.

Какой был бы лучший способ использовать BufferedReader в Котлине?

Ответ 1

Вы можете использовать bufferedReader так

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

Ответ 2

Если вы все еще хотите прочитать его по очереди, вы можете использовать некоторые функции расширения из std lib и сделать это следующим образом:

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

или, альтернативно, используя "функциональный" подход:

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

используя useLines, вам не нужно явно закрывать читателя, функция extensionLines extensions сделает это за вас!

Просто добавьте их для справки.. cheers

Ответ 3

Благодаря ссылке Жуана Гонсалвеша на stdlib я обнаружил, что вы можете использовать forEachLine для обхода читателя, если это необходимо.

Ответ 4

используйте такой код

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

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

    } else {

    return "unsuccessful"

    }

Ответ 5

Другой способ - использовать цикл for:

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

Хотя это не так кратко, как принятый ответ, он позволит вам выполнить цикл и выполнить какую-то логику, не накапливая все в одну строку, как показано ниже

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

Ответ 6

Вы также можете попробовать использовать метод "forEachLine".

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

он также автоматически закроет поток после прочтения последней строки

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

fun Reader.forEachLine(action: (String) → Unit)
Выполняет итерацию по каждой строке этого считывателя, вызывает действие для каждой прочитанной строки и закрывает считыватель после его завершения.