Самый простой способ получить массив байт из `InputStream` в Kotlin:.
Ниже — разделы про пример с файлом, почему важно закрывать поток и если поток большой, чтобы быстро понять устройство материала, практические ограничения и типовые точки отказа.
Самый простой способ получить массив байт из InputStream в Kotlin:
val bytes: ByteArray = inputStream.use { stream ->
stream.readBytes()
}
readBytes() читает поток целиком и возвращает ByteArray. use автоматически закроет поток после чтения, даже если произойдет ошибка
Пример с файлом
import java.io.File
fun main() {
val file = File("photo.png")
val bytes = file.inputStream().use { input ->
input.readBytes()
}
println("Прочитано байт: ${bytes.size}")
}
Если файл существует, программа выведет размер массива байт. Это удобно для загрузки изображения, чтения ресурса, отправки файла в API или сохранения данных в базу
Почему важно закрывать поток
InputStream связан с ресурсом: файлом, сетью, asset или response body. Если его не закрыть, приложение может держать лишние файловые дескрипторы и память. В Kotlin для этого есть use
Плохо:
val bytes = inputStream.readBytes()
Лучше:
val bytes = inputStream.use { it.readBytes() }
Если поток большой
readBytes() читает все содержимое в память. Для маленького файла это нормально. Для видео, больших архивов или длинных сетевых ответов лучше читать поток частями через буфер и писать в файл или обрабатывать кусками
val buffer = ByteArray(8 * 1024)
var read: Int
while (input.read(buffer).also { read = it } != -1) {
println("Прочитано в блоке: $read")
}
Так вы не держите весь файл в памяти сразу
Если размер файла заранее неизвестен, всегда задавайте себе вопрос: «Я точно хочу держать все байты в памяти?» Для аватарки или небольшого JSON-ответа да. Для архива или видео — почти всегда нет
Android-пример
Если файл лежит в assets, можно сделать так:
val bytes = assets.open("data.bin").use { input ->
input.readBytes()
}
Для res/raw обычно используют resources.openRawResource(R.raw.name)
Когда нужен ByteArray
ByteArray часто нужен, когда библиотека принимает не файл, а сырые данные: загрузка изображения в память, отправка multipart-запроса, шифрование, расчет hash, сохранение вложения из сети. Если вы просто копируете файл из одного места в другое, необязательно превращать его в массив байт. Иногда лучше копировать поток в поток
input.use { source ->
output.use { target ->
source.copyTo(target)
}
}
Такой вариант экономнее по памяти для больших файлов
Частые ошибки
Читать большой файл целиком
Если файл может быть десятки или сотни мегабайт, readBytes() может привести к нехватке памяти
Забыть use
Без use поток может остаться открытым. Это особенно неприятно в Android и серверном коде
Путать ByteArray и String
ByteArray — это байты. Если вам нужен текст, укажите кодировку:
val text = bytes.toString(Charsets.UTF_8)
Что почитать дальше по Kotlin
Если нужен общий маршрут по теме, откройте рубрику Kotlin. Для соседних задач пригодятся эти разборы:
- UUID Android-устройства в Kotlin ViewModel: как получить безопасно
- Как получить UUID Android-устройства в Kotlin Jetpack
- Coroutines в Kotlin: первый async-пример
- Inline в Kotlin: что это и когда использовать



