Недавно я видел код для чтения всего содержимого InputStream
строки в Kotlin, например:
// input is of type InputStream
val baos = ByteArrayOutputStream()
input.use { it.copyTo(baos) }
val inputAsString = baos.toString()
А также:
val reader = BufferedReader(InputStreamReader(input))
try {
val results = StringBuilder()
while (true) {
val line = reader.readLine()
if (line == null) break
results.append(line)
}
val inputAsString = results.toString()
} finally {
reader.close()
}
И даже это выглядит более плавным, поскольку автоматически закрывает InputStream
:
val inputString = BufferedReader(InputStreamReader(input)).useLines { lines ->
val results = StringBuilder()
lines.forEach { results.append(it) }
results.toString()
}
Или небольшое изменение этого:
val results = StringBuilder()
BufferedReader(InputStreamReader(input)).forEachLine { results.append(it) }
val resultsAsString = results.toString()
Затем эта функциональная складчатая штуковина:
val inputString = input.bufferedReader().useLines { lines ->
lines.fold(StringBuilder()) { buff, line -> buff.append(line) }.toString()
}
Или плохой вариант, который не закрывает InputStream
:
val inputString = BufferedReader(InputStreamReader(input))
.lineSequence()
.fold(StringBuilder()) { buff, line -> buff.append(line) }
.toString()
Но все они неуклюжие, и я постоянно нахожу новые и разные версии одного и того же ... а некоторые из них даже не закрывают InputStream
. Какой неуклюжий (идиоматический) способ читать InputStream
?
Примечание: этот вопрос намеренно написан и на него дан ответ автора ( вопросы с ответами), так что идиоматические ответы на часто задаваемые темы Kotlin присутствуют в SO.
источник
use
or,useLines
выполняет функцию блока для того, что «используется». например ,inputStream.useText { text -> ... }
С другой стороны, когда я прочитал «READTEXT» Я ожидаю , что функция , которая возвращает текст:val inputAsString = inputStream.readText()
.use
в этом отношении он больше похож на функции. по крайней мере, в контексте этих вопросов и ответов. может быть найден новый глагол ...readTextAndClose()
использовал этот пример, чтобы избежать конфликта сreadText()
шаблонами незакрытия и сuse
шаблонами, требующими лямбда, поскольку я не пытаюсь ввести новую функцию stdlib, я не хочу делать больше, чем указывать на использование расширения, чтобы сэкономить труд в будущем.Пример, который считывает содержимое InputStream в строку
Для справки - файл чтения Kotlin
источник
Paths.get()
метод. 2) Для потоков - функция try-resource (В котлине: .use {})【Метод 1 | Закрыть поток вручную】
inputStream.readBytes()
требует вручную закрыть поток: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/read-bytes.html【Метод 2 | Автоматически закрывать поток】
Вы можете указать кодировку внутри
bufferedReader()
, по умолчаниюUTF-8
: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/java.io.-input-stream/buffered-reader.htmlbufferedReader()
это обновленная версияreader()
, она более универсальна: как именно bufferedReader () работает в Kotlin?use()
может автоматически закрыть поток, когда блок будет выполнен: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/use.htmlисточник