Если используемая вами среда не предоставляет вам полноценную реализацию InputStream
, остается только написать свою собственную. Очень похоже на то, что сделали разработчики ktor: ByteReadChannel
- это просто абстракция «чтения байтов из канала».
Эта абстракция живет в общей части и позволяет писать приложение и бизнес-логику вокруг нее.
Ключ к выполнению этой работы в контексте мультиплатформенного проекта Kotlin заключается в том, что фактическая реализация должна быть представлена в отдельных частях платформы. Специфический код JVM проекта ktor на самом деле имеет реализацию, которая использует InputStream
: InputStream.toByteReadChannel
.
Вам, конечно, не обязательно делать это как ваш пример из проекта ktor и моделировать все, начиная с байтовых каналов и заканчивая представлениями файлов. Если вы хотите использовать каркасные классы Kotlin, Sequence может оказаться полезным. Это может выглядеть примерно так:
// in common
interface FileFetcher {
fun fetch(): Sequence<Byte>
}
expect fun fileFetcher(source: String): FileFetcher
// in jvm
class JvmFileFetcher(val input: java.io.InputStream): FileFetcher {
override fun fetch(): Sequence<Byte> = input.readBytes().asSequence()
}
actual fun fileFetcher(source: String): FileFetcher {
val input = java.net.URL(source).openStream()
return JvmFileFetcher(input)
}
Вы определяете интерфейс FileFetcher
вместе с заводской функцией fileFetcher
в общей части. Используя ключевое слово expect
в функции fileFetcher
, вам необходимо предоставить реализации для каждой платформы, которые вы определяете. Используйте интерфейс FileFetcher
в общей части для реализации вашей логики (расшифровка содержимого файла и т. Д.). Информацию о том, как с ним работать, см. В документации по Sequence
.
Затем реализуйте заводскую функцию для всех платформ и используйте на них ключевое слово actual
. Затем вам нужно написать специфичные для платформы реализации FileFetcher
. Мой пример показывает, как работает JVM-версия интерфейса FileFetcher
.
Пример, конечно, очень простой, и вы, вероятно, не захотите делать это в точности так (по крайней мере, потребуется некоторая буферизация). Кроме того, в рамках JVM вы также можете легко использовать свою любимую сетевую / HTTP-библиотеку.