[英]Writing elements to a file as they are dequeued from the queue : Scala fs2 Stream
[英]remove the filtered line from the file using scala fs2 file streaming
如何使用fs2從當前流文件中刪除filtered
行並獲取過濾的行數作為返回類型?
例如:如果old.txt
包含由換行符 (\\n) 分隔的字符串:
john
sam
chen
yval
....
和val myList = List("chen","yval")
。
def converter[F[_]](implicit F: Sync[F]): F[Unit] =
io.file.readAll[F](Paths.get("testdata/old.txt"), 4096)
.through(text.utf8Decode)
.through(text.lines)
.filter(s => myList.contains(s))//remove this from the old file and write to new file
.intersperse("\n")
.through(text.utf8Encode)
.through(io.file.writeAll(Paths.get("testdata/new.txt")))
.compile.drain
// at the end of the universe...
val u: Unit = converter[IO].unsafeRunSync()
您可以使用Stream
類的observe 方法。
您正在尋找一個函數def converter[F[_]: Sync]: F[Int]
,它產生一個計算F[Int]
其結果(類型Int
)是過濾行的數量,其效果是寫這些行到輸出文件。 要遵循管道的比喻,你想你的過濾流饋送到兩個輸出,一個是結果,而一個用於效果。 您可以使用功能observe來做到這一點,定義為
def observe(sink: Sink[F, O])(implicit F: Effect[F], ec: ExecutionContext): Stream[F, O]
Sink[F,O]
是函數Stream[F, O] => Stream[F, Unit]
的別名。 在您的情況下,接收器是將過濾后的流寫入輸出文件的代碼的一部分:
def writeToFile[F[_]: Sync]: Sink[F, String] =
_.intersperse("\n")
.through(text.utf8Encode)
.through(io.file.writeAll(Paths.get("testdata/new.txt")))
另一個輸出是減少,或者更確切地說是折疊,
def converter[F[_]](implicit F: Effect[F], ec: ExecutionContext): F[Int] =
io.file.readAll[F](Paths.get("testdata/old.txt"), 4096)
.through(text.utf8Decode)
.through(text.lines)
.filter(s => myList.contains(s))
.observe(writeToFile[F])
.compile
.fold[Int](0)( (c, _) => c+1)
}
注意:對於此解決方案,您需要將F
的類型類限制為Effect
,並且您需要使用ExecutionContext
。 fold
在ToEffect
類中定義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.