FS2流未读InputStream

时间:2018-08-21 01:37:27

标签: scala fs2

我想将fs2.Stream转换为java.io.InputStream,以便将输入流传递到http框架(Finch和Akka Http)。

我发现了一个fs2.io.toInputStream,但这不起作用(它什么也不打印):

import java.io.{ByteArrayInputStream, InputStream}

import cats.effect.IO
import scala.concurrent.ExecutionContext.Implicits.global

object IOTest {

  def main(args: Array[String]): Unit = {
    val is: InputStream = new ByteArrayInputStream("test".getBytes)
    val stream: fs2.Stream[IO, Byte] = fs2.io.readInputStream(IO(is), 128)

    val test: Seq[InputStream] = stream.through(fs2.io.toInputStream).compile.toList.unsafeRunSync()

    println(scala.io.Source.fromInputStream(test.head).mkString)
  }
}

据我了解,当我运行.unsafeRunSync()时,它会消耗整个流,因此即使返回Seq[InputStream],底层输入流也已被消耗。

有什么方法可以将fs2.Stream[IO, Byte]转换为java.io.InputStream而不被消耗?

感谢!

2 个答案:

答案 0 :(得分:0)

问题在于compile被过早调用。我确定fs2.io.toInputStream可以正确执行操作,并将创建的InputStream用括号括起来。这意味着InputStream本身必须在{em>内部内访问Stream(例如,在map / flatMap调用中):

val wire: fs2.Stream[IO, Byte] = ???

val result: fs2.Stream[IO, String] = for {
  is <- wire.through(fs2.io.toInputStream)
  str = scala.io.Source.fromInputStream(is).mkString //<--- use the InputStream here
} yield str

println( result.compile.lastOrError.unsafeRunSync() ) //<--- compile at the _very_ end

输出:

  

测试

答案 1 :(得分:-1)

看起来Finch具有fs2支持https://github.com/finagle/finch/tree/master/fs2,而Akka也具有流实现,并且还有fs2-Akka Stream互操作库,例如https://github.com/krasserm/streamz/tree/master/streamz-converter

因此,我建议您看一下这些实现,因为它们会处理资源生命周期。可能您不需要整个库,但它只是指导。

如果您从fs2开始进入“安全区”,为什么要离开那里:)