Объедините разделители для создания потока слов из текстового файла, используя Akka Streams - PullRequest
1 голос
/ 22 сентября 2019

У меня есть следующий код, который вычисляет частоту слов в текстовом файле:

implicit val system: ActorSystem = ActorSystem("words-count")
implicit val mat = ActorMaterializer()
implicit val ec: ExecutionContextExecutor = system.dispatcher

val sink = Sink.fold[Map[String, Int], String](Map.empty)({
    case (count, word) => count + (word -> (count.getOrElse(word, 0) + 1))
  })    

FileIO.fromPath(Paths.get("/file.txt"))
        .via(Framing.delimiter(ByteString(" "), 256, true).map(_.utf8String))
        .toMat(sink)((_, right) => right)
        .run()
        .map(println(_))
        .onComplete(_ => system.terminate())

В настоящее время он использует пробел в качестве разделителя, но игнорирует разрывы строк ("\n").Могу ли я использовать пробелы и разрывы строк в качестве разделителей в одном потоке, т.е. есть ли способ их объединить?

1 Ответ

1 голос
/ 22 сентября 2019

Вы можете установить разделитель как \n, а затем разделить строки пробелом, используя flatMapConcat:

FileIO
    .fromPath(Paths.get("file.txt"))
    .via(Framing.delimiter(ByteString("\n"), 256, true).map(_.utf8String))
    .flatMapConcat(s => Source(s.split(" ").toList)) //split line by space 
    .toMat(sink)((_, right) => right)
    .run()
    .map(println(_))
    .onComplete(_ => system.terminate())
...