Как из InputStream получить массив байт в Kotlin

Самый простой способ получить массив байт из `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. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x