Как эффективно записать JSON в файл при сохранении ссылочной прозрачности? - PullRequest
1 голос
/ 06 августа 2020

Моя основная цель - эффективно записать JSON строк в файл, сохраняя при этом ссылочную прозрачность. У меня есть два основных вопроса:

  1. Эффективна ли запись в файл построчно? Или есть лучший способ, где я могу буферизовать json и записывать его партиями (я предполагаю, что это быстрее, чем запись по строкам)
  2. Как я могу поддерживать ссылочную прозрачность при записи в файл? (насколько я понимаю, мне нужно обернуть часть кода в монаду ввода-вывода, но я не уверен, как правильно это сделать или как безопасно запустить). Дальнейшее чтение приветствуется.

Я создал образец кода, чтобы показать, чего я достиг в своем коде (только фрагмент):

import io.circe.generic.auto._, io.circe.syntax._

for (u <- someList) println(u.asJson.noSpaces)
// resulting Json (sample):
// {"id":"1","name":"Mr Foo","roles":["Chief Foo Officer"],"phone_number":null}
// {"id":"2","name":"Mr Bar","roles":["Chief Bar Officer"],"phone_number":null}
// .....

1 Ответ

1 голос
/ 06 августа 2020

Если список большой, вы можете использовать Stream , например:

import cats.effect.{Blocker, ContextShift, IO, Sync}
import fs2.Stream
import io.circe.Encoder
import io.circe.syntax._
import java.nio.file.{Path, Paths}

def writeToFileAsJsons[A : Encoder, F[_] : Sync : ContextShift](data: List[A], path: Path, blocker: Blocker): F[Unit] =
  Stream
  .emits(data)
  .covary[F]
  .map(_.asJson.noSpaces)
  .through(fs2.text.utf8Encode)
  .through(fs2.io.file.writeAll(path, blocker))
  .compile
  .drain

И вызвать метод, например:

val program: IO[Unit] =
  Blocker[IO].use { blocker =>
    writeToFileAsJsons[Int, IO](
      data = List(1, 2, 3),
      path = Paths.get("foo", "bar.txt"),
      blocker
    )
  }

( пока есть ContextShift для IO в области действия)

Если список действительно большой, вы можете захотеть иметь Stream с самого начала, а если он не такой большой, не беспокойтесь об этом слишком сильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...