Как прочитать всё содержимое InputStream в строку в Kotlin?
Лучший способ: использование extension-функций Kotlin
В Kotlin есть встроенные extension-функции для InputStream, которые делают чтение в строку тривиальным. Рекомендуемый способ — использовать функцию .bufferedReader() в сочетании с .readText().
Вот самый простой и правильный вариант:
fun readInputStreamAsString(stream: InputStream): String {
return stream.bufferedReader().readText()
}
Или ещё короче (однострочник):
val content = stream.bufferedReader().readText()
Разбор решения
.bufferedReader()— это extension-функция, которая оборачиваетInputStreamвBufferedReaderс кодировкой UTF-8 по умолчанию. Если нужна другая кодировка, можно передать её параметром:stream.bufferedReader(Charsets.ISO_8859_1)..readText()— читает все содержимое ридера в строку. Она автоматически закрывает поток после чтения (реализуетuse).- Поток закрывается автоматически благодаря тому, что
bufferedReader()возвращает объект, реализующийCloseable, иreadText()вызываетclose()внутри.
Для больших потоков
Если вы работаете с очень большими данными (например, многогигабайтный файл), чтение всего в память может быть опасным. В таких случаях используйте построчную обработку:
stream.bufferedReader().use { reader ->
reader.lines().forEach { line ->
// обрабатываем каждую строку
}
}
Альтернативные варианты
stream.readBytes().decodeToString()— если вы уже получили массив байт, можно преобразовать в строку:stream.readBytes().decodeToString(). Но это менее эффективно для больших данных.- Java-style через Scanner — не рекомендуется, так как это более громоздко.
Пример с сетевым ответом
import java.net.URL
fun main() {
val url = URL("https://example.com/data.txt")
val content = url.openStream().bufferedReader().readText()
println(content)
}
Важно: управление ресурсами
Если вы не используете readText() напрямую, всегда оборачивайте работу с потоком в .use { } для гарантированного закрытия:
stream.bufferedReader().use { reader ->
val text = reader.readText()
// используем text
}
Функция use гарантирует закрытие ресурса даже при возникновении исключения.
Таким образом, ответ на ваш вопрос: используйте stream.bufferedReader().readText() — это самый короткий, безопасный и идиоматичный способ в Kotlin.
Альтернативный подход: через readBytes() с явной кодировкой
Если вы предпочитаете работать на более низком уровне или вам нужно явно управлять кодировкой, можно использовать комбинацию readBytes() и String:
fun readStream(stream: InputStream, charset: Charset = Charsets.UTF_8): String {
return stream.use { it.readBytes().toString(charset) }
}
Здесь stream.use { } гарантирует закрытие потока, а readBytes() читает все байты в массив. Затем toString(charset) преобразует их в строку с нужной кодировкой.
Когда это может быть полезно?
- Если вам нужно обработать байты перед преобразованием в строку (например, декомпрессия).
- Если вы работаете с нестандартными кодировками (например, CP1251) и хотите явно указать её.
Недостатки
readBytes()загружает все данные в память, что может быть проблемой для очень больших потоков.- Требует явного вызова
useдля закрытия (хотя это хорошая практика).
Этот вариант менее идиоматичен, чем bufferedReader().readText(), но даёт больше контроля. Выбирайте в зависимости от задачи.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги