【问题标题】:How to parse "streamed" json objects with json4s?如何使用 json4s 解析“流式传输”的 json 对象?
【发布时间】:2018-02-17 10:22:39
【问题描述】:

我有一个流式源,它可以生成许多没有分隔符(或中间只有空格)的 JSON 对象。如果我将它传递给 json4s parse 函数,它只会为第一个对象生成 AST。

作为一种解决方法,我可以手动解析它,然后通过添加适当的括号和逗号将其转换为 JSON 数组,或者将其分块并在每个块上调用 parse

不过,这是rather common format,所以我确定问题已经解决了。我只是在 json4s 文档中找不到它的 API。

【问题讨论】:

  • jawn 似乎通过ValueStream 支持这一点。 jhttps://index.scala-lang.org/non/jawn/jawn-parser - 如果你想用它进行适当的流处理:github.com/circe/circe-fs2 - 用 circe 解码。
  • @Reactormonk,我并不是很热衷于添加另一个 json 库依赖项,但是 jawn 可以产生 json4s AST,所以如果 json4s 本身不支持这个,我不会排除它。跨度>
  • 我发现 circe 编解码器比 json4s 的手动编解码器更易于维护。
  • @Reactormonk,不需要带有 json4s 和案例类的手动编解码器,至少在我的用例中是这样。老实说,我不知道它实际上是如何工作的。

标签: json scala json4s


【解决方案1】:

如果您从InputStream 读取它,则使用BufferedInputStream 包装器和mark()read()reset() 调用来跳过parse() 调用之间的空格:

val in = new BufferedInputStream(new FileInputStream("/tmp/your.json"))
try {
  var continue = true
  in.mark(1)
  do {
    in.reset()         

    // <-- here should be call for parse

    // skip white spaces or exit if EOF found
    var b = 0
    do {
      in.mark(1)
      b = in.read()
      if (b < 0) continue = false
    } while (Character.isWhitespace(b))
  } while (continue)
} finally in.close()

编辑:今天我发布了0.11.0 version of jsoniter-scala,它具有解析流式 JSON 值或 JSON 数组的新功能,而无需将所有值保存在内存中。

【讨论】:

  • 这就是我手动分块的意思(好吧,加上一些类型的体操来获取输入流)。我希望在 json4s 中有对此的支持。
猜你喜欢
  • 1970-01-01
  • 2019-06-23
  • 2014-07-05
  • 2014-09-18
  • 1970-01-01
  • 2015-12-02
  • 2021-11-25
  • 2019-08-16
  • 1970-01-01
相关资源
最近更新 更多