在Akka溪流中的流内分裂

在Akka溪流中的流内分裂,akka,akka-stream,Akka,Akka Stream,我试图想出一个解决方案,将接收到的一个传入字符串拆分为多个字符串。我一直在研究,在Akka Streams的早期版本中,似乎有一个类Transformer,您可以扩展它来进行这种转换 在我使用的版本(RC2)中有Stages,但我不确定如何实现拆分模式 Source.actorPublisher[String](MyActor.props). .XXXXX(_.split("\n")) .map(...) .to(Sink(...)) 我正在寻找XXXXX组件,该组件允许我输入字符串,并返回一

我试图想出一个解决方案,将接收到的一个传入字符串拆分为多个字符串。我一直在研究,在Akka Streams的早期版本中,似乎有一个类
Transformer
,您可以扩展它来进行这种转换

在我使用的版本(RC2)中有
Stage
s,但我不确定如何实现拆分模式

Source.actorPublisher[String](MyActor.props).
.XXXXX(_.split("\n"))
.map(...)
.to(Sink(...))

我正在寻找
XXXXX
组件,该组件允许我输入
字符串
,并返回一系列
字符串
,并将每个字符串发送到流的其余部分。

我同意@jrudolph的观点,即
mapConcat
可能就是您要寻找的。下面是一个演示此方法的快速示例:

  val strings = List(
  """hello
     world
     test
     this""",
     """foo
     bar
     baz
     """

  )

  implicit val system = ActorSystem("test")
  implicit val mater = ActorFlowMaterializer()
  Source(strings).
    mapConcat(_.split("\n").map(_.trim).toList).
    runForeach(println)
如果运行此代码,您将看到打印出以下内容:

hello
world
test
this
foo     
bar
baz
Akka为这类问题提供了帮助函数

假设您的字符集是UTF-8,您可以编写一个函数,该函数接受分隔的
字符串的最大大小
值,并返回可以执行拆分的

import akka.stream.scaladsl.Framing
import akka.util.ByteString

val newLineSplitter : (Int) => Flow[String, String, NotUsed] = 
  (maxLineSize) =>
    Flow[String]
      .map(ByteString.apply)
      .via(Framing delimiter (ByteString("\n"), maxLineSize))
      .via(Flow[ByteString] map (_.utf8String))

如果结果元素始终仅依赖于单个输入元素,则可以使用
mapConcat
。如果依赖关系更复杂,则可以使用(有状态)阶段。除此之外,通常可以从
flatMap
的角度来考虑
mapConcat
。名称不同是因为某些单子定律不成立。