Я недавно видел код для чтения всего содержимого InputStream
в строку в Котлин, такие как:В Kotlin, как я могу прочитать все содержимое InputStream в String?
// 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()
}
И даже это, что выглядит более гладкой, так как он автоматически -closes the 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
?
Примечание:этот вопрос намеренно написан и ответил автором (Self-Answered Questions), так что идиоматические ответы на часто задаваемые вопросы Котлин присутствуют в SO.
Я думаю, что "READTEXT" был бы лучше имя чем «useText» для функции расширения, которую вы предлагаете. Когда я читаю «useText», я ожидаю такую функцию, как 'use' или' useLines', которая выполняет блок-функцию на том, что «используется». например 'inputStream.useText {text -> ...}' С другой стороны, когда я читаю «readText», я ожидаю функцию, которая возвращает текст: 'val inputAsString = inputStream.readText()'. – mfulton26
Правда, но readText уже имеет неправильный смысл, поэтому хотел означать, что это больше похоже на функции 'use' в этом отношении. по крайней мере, в контексте этого Q & A. возможно, новый глагол можно найти ... –
@ mfulton26 Я пошел с 'readTextAndClose()' для этого примера, чтобы избежать конфликта с 'readText()' шаблонами не закрытия и шаблонами 'use', требующими лямбда, так как я «Я не пытаюсь ввести новую функцию stdlib. Я не хочу делать больше, чем говорить об использовании расширений, чтобы сохранить будущий труд. –