Kotlin 中的多平台 InputStream 替代方案?

Posted

技术标签:

【中文标题】Kotlin 中的多平台 InputStream 替代方案?【英文标题】:Multi-platform InputStream Alternative in Kotlin? 【发布时间】:2019-03-31 13:06:18 【问题描述】:

我正在寻找输入流的多平台替代方案。我的具体任务是通过 https 从远程服务器获取加密文件并按需解密。

在 Java 领域,我将实现 InputStream,它代理读取来自 https 库的输入流。如何在针对多个平台的 kotlin 中做同样的事情。

我看到 ktor 返回一个 ByteReadChannel,但我不知道哪些函数。

我迷路了,不知道从哪里开始。提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

如果您使用的框架没有为您提供完整的InputStream 实现,那么剩下的唯一机会就是编写您自己的。很像 ktor 开发人员所做的:ByteReadChannel 只是“从通道读取字节”的抽象。 这种抽象存在于公共部分,并允许围绕它编写应用程序和业务逻辑。

在 Kotlin 多平台项目的上下文中进行这项工作的关键是,需要在平台特定部分中提供实际实现。 ktor 项目的 JVM 特定代码实际上有一个使用 InputStream 的实现:InputStream.toByteReadChannel

您当然不必像您在 ktor 项目中的示例那样对从字节通道到文件表示的所有内容进行建模。如果您想利用 Kotlin 框架类,Sequences 可能会很方便。这可能看起来像这样:

// 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。通过在fileFetcher 函数上使用expect 关键字,您需要为您定义的所有目标平台提供特定于平台的实现。使用公共部分中的FileFetcher 接口来实现您的逻辑(解密文件内容等)。请参阅Sequence 的文档了解如何使用它。

然后为所有平台实现工厂函数并在它们上使用actual关键字。然后,您将需要编写FileFetcher 的特定于平台的实现。我的示例显示了 JVM 版本的 FileFetcher 接口。

这个例子当然是非常基本的,你可能不想完全像这样(我猜至少需要一些缓冲)。此外,在 JVM 部分中,您还可以轻松利用自己喜欢的网络/HTTP 库。

【讨论】:

以上是关于Kotlin 中的多平台 InputStream 替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin 与 Objective-C 框架的多平台/本机互操作性

Kotlin 中的多变量 let

Android Kotlin:无法将 InputStream 保存为文件

在 Kotlin 中,如何将 InputStream 的全部内容读入字符串?

Room 数据库中的多对多关系。 Kotlin Junction 类被忽略

安卓 | Kotlin:应用程序从 InputStream 读取到缓冲区问题