我正在使用Alpakka-FTP,但也许我正在寻找一般的akka-stream模式。 FTP连接器可以列出文件或检索它们:
def ls(host: String): Source[FtpFile, NotUsed]
def fromPath(host: String, path: Path): Source[ByteString, Future[IOResult]]
理想情况下,我想创建一个这样的流:
LIST
.FETCH_ITEM
.FOREACH(do something)
但是我无法使用上面写的两个函数创建这样的流。我觉得我应该能够使用Flow
到达那里,比如
Ftp.ls
.via(some flow that uses the Ftp.fromPath above)
.runWith(Sink.foreach(do something))
这是否可行,只考虑上面的ls
和fromPath
函数?
编辑:
我能够使用一个演员和mapAsync
来解决这个问题,但我仍然觉得它应该更直接。
class Downloader extends Actor {
override def receive = {
case ftpFile: FtpFile =>
Ftp.fromPath(Paths.get(ftpFile.path), settings)
.toMat(FileIO.toPath(Paths.get("testHDF.txt")))(Keep.right)
.run() pipeTo sender
}
}
val downloader = as.actorOf(Props(new Downloader))
Ftp.ls("test_path", settings)
.mapAsync(1)(ftpFile => (downloader ? ftpFile) (3.seconds).mapTo[IOResult])
.runWith(Sink.foreach(res => println("got it!" + res)))
答案 0 :(得分:1)
您应该可以将flatMapConcat
用于此目的。您的具体示例可以重写为
Ftp.ls("test_path", settings).flatMapConcat{ ftpFile =>
Ftp.fromPath(Paths.get(ftpFile.path), settings)
}.runWith(FileIO.toPath(Paths.get("testHDF.txt")))
文档here。