我想将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
而不被消耗?
感谢!
答案 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开始进入“安全区”,为什么要离开那里:)