Мультиплатформенная альтернатива InputStream в Котлине? - PullRequest
0 голосов
/ 26 октября 2018

Я ищу многоплатформенную альтернативу входным потокам. Моя конкретная задача - получить зашифрованный файл с удаленного сервера через https и расшифровать его по требованию.

На земле Java я бы реализовал InputStream, который передает чтения в поток ввода из библиотеки https. Как я могу сделать то же самое в kotlin для нескольких платформ.

Я вижу, что ktor возвращает ByteReadChannel , но я не знаю, какие функции.

Я потерялся и не знаю, с чего начать. Заранее благодарны за Вашу помощь.

1 Ответ

0 голосов
/ 25 ноября 2018

Если используемая вами среда не предоставляет вам полноценную реализацию 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-библиотеку.

...