我正在尝试运行一个简单的Akka Stream File Sink示例,但没有成功。我可以创建一个Source,运行Flow然后创建一个文件但ByteString没有写入文件。然而,如果我尝试将流输出打印到控制台,我可以这样做。我在这里错过了什么吗?
import akka.stream._
import akka.stream.scaladsl._
import akka.{ NotUsed, Done}
import akka.actor.ActorSystem
import akka.util.ByteString
import scala.concurrent._
import scala.concurrent.duration._
import java.nio.file.Paths
object First extends App {
val source: Source[Int, NotUsed] = Source ( 1 to 100)
implicit val system = ActorSystem("QuickStart")
implicit val materializer = ActorMaterializer()
// works: prints 1-100
//source.runForeach(println) (materializer)
val factorials = source.scan(BigInt(1))((acc,next) => acc * next)
// there is no content in the Sink (file)
/**val result =
factorials
.map(num => ByteString(s"${num}\n"))
.runWith(FileIO.toPath(Paths.get("factorials.txt")))
**/
def lineSink(fileName: String): Sink[String, Future[IOResult]] =
Flow[String]
.map(s => ByteString(s + "\n"))
.toMat(FileIO.toPath(Paths.get(fileName))) (Keep.right)
//There is no content in the Sink.
factorials.map(_.toString).runWith(lineSink("factorials.txt"))
system.terminate()
}
build.sbt 有:
name := "akkaGuide"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-stream" % "2.4.10"
)
提前感谢您的时间。
答案 0 :(得分:6)
我想你可能会过早地终止。请等待Future
完成:
val result = factorials.map(_.toString).runWith(lineSink("factorials.txt"))
import system.dispatcher
result.onComplete { _ => system.terminate() }
答案 1 :(得分:0)
看看这个工作示例:
package ru.io
import java.io.File
import akka.actor.ActorSystem
import akka.stream.scaladsl._
import akka.stream.{ActorMaterializer, ClosedShape}
import akka.util.ByteString
import scala.util.{Failure, Success}
object WriteStreamApp extends App {
implicit val actorSystem = ActorSystem()
implicit val flowMaterializer = ActorMaterializer()
import actorSystem.dispatcher
// Source
val source = Source(1 to 10000).filter(isPrime)
// Sink
val sink = FileIO.toFile(new File("src/main/resources/prime.txt"))
// выход для файла
val fileSink = Flow[Int]
.map(i => ByteString(i.toString))
.toMat(sink)((_, bytesWritten) => bytesWritten)
val consoleSink = Sink.foreach[Int](println)
// отправить простые числа в оба стока: файл и консоль, используя граф-API
val graph = GraphDSL.create(fileSink, consoleSink)((file, _) => file) { implicit builder => (file, console) =>
import GraphDSL.Implicits._
val broadCast = builder.add(Broadcast[Int](2))
source ~> broadCast ~> file
broadCast ~> console
ClosedShape
}
val materialized = RunnableGraph.fromGraph(graph).run()
// убедитесь, что выходной файл закрыт и завершение работы системы завершено
materialized.onComplete {
case Success(_) =>
actorSystem.terminate()
case Failure(e) =>
println(s"Failure: ${e.getMessage}")
actorSystem.terminate()
}
def isPrime(n: Int): Boolean = {
if (n <= 1) false
else if (n == 2) true
else !(2 until n).exists(x => n % x == 0)
}
}