简体   繁体   English

使用 scala fs2 文件流从文件中删除过滤的行

[英]remove the filtered line from the file using scala fs2 file streaming

how to remove the filtered lines from the current streaming file using fs2 and get the count of filtered lines as the return type?如何使用fs2从当前流文件中删除filtered行并获取过滤的行数作为返回类型?

ex: If the old.txt contains strings separated by a newline (\\n):例如:如果old.txt包含由换行符 (\\n) 分隔的字符串:

 john
 sam
 chen
 yval
 ....

and val myList = List("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()

You can use the observe method of the Stream class.您可以使用Stream类的observe 方法

You are looking for a function def converter[F[_]: Sync]: F[Int] , which produces a computation F[Int] whose result (of type Int ) is the number of filtered lines, and whose effect is to write those lines to the output file.您正在寻找一个函数def converter[F[_]: Sync]: F[Int] ,它产生一个计算F[Int]其结果(类型Int )是过滤行的数量,其效果是写这些行到输出文件。 To follow a plumbing analogy, you want to feed your filtered stream to two outputs, one for the result, and one for the effect.要遵循管道的比喻,你想你的过滤流馈送到两个输出,一个是结果,而一个用于效果。 You can do this using the function observe , defined as您可以使用功能observe来做到这一点,定义为

def observe(sink: Sink[F, O])(implicit F: Effect[F], ec: ExecutionContext): Stream[F, O] 

A Sink[F,O] is an alias for a function Stream[F, O] => Stream[F, Unit] . Sink[F,O]是函数Stream[F, O] => Stream[F, Unit]的别名。 In your case, the sink is the part of your code that writes your filtered stream into the output file:在您的情况下,接收是将过滤后的流写入输出文件的代码的一部分:

def writeToFile[F[_]: Sync]: Sink[F, String] = 
  _.intersperse("\n")
  .through(text.utf8Encode)
  .through(io.file.writeAll(Paths.get("testdata/new.txt")))

The other output is to reduce, or rather fold,另一个输出是减少,或者更确切地说是折叠,

  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)
}

Note : for this solution you need to restrict the type-class of F to be Effect , and you need to use an ExecutionContext .注意:对于此解决方案,您需要将F的类型类限制为Effect ,并且您需要使用ExecutionContext The fold is defined in the ToEffect class. foldToEffect类中定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM