簡體   English   中英

使用 scala fs2 文件流從文件中刪除過濾的行

[英]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 foldToEffect類中定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM