我的用例与this entry相似,希望从JSON对象中读取内部的巨大数组(文本为数GB):
{ "a": "...", // root level fields to be read, separately
...
"bs": [ // the huge array, most of the payload (can be multiple GB's)
{...},
...
]
}
输入可用Source[ByteString,_]
(Akka流)提供,我在其他地方使用Circe进行JSON解码。
我可以看到两个挑战:
以流方式读取bs
数组(获取Source[B,_]
以供使用)。
将原始流拆分为两个,因此我可以在数组开始之前读取和分析根级别字段。
您是否有解决此类用例的指南?到目前为止,我已经检查了akka-stream-json和circe-iteratee。
akka-stream-json
看起来很像,但维护得不是很好。
circe-iteratee
似乎没有与Akka Streams集成。
答案 0 :(得分:1)
Jawn有一个异步解析器:https://github.com/non/jawn/blob/master/parser/src/main/scala/jawn/AsyncParser.scala
但是由于其顺序来源,很难为JSON编写高效的异步解析器。
如果可以切换到同步解析,则可以使用jsoniter-scala-core并编写一个简单的自定义编解码器,该编解码器将跳过除“ bs”之外的所有不需要的键/值对,然后快速解析所需的数据而无需保持或在内存中排列内容。
答案 1 :(得分:0)
我看到这需要一个全新的库,用于流JSON解码。
类似的东西:
case class A(a: Int, bs: Source[B,_])
val src: Source[ByteString,_] = ???
src.as[A]
我的临时解决方案是通过jq
和sed
“按摩” JSON,以便每个B
都在自己的行上。这样,我就可以逐行使用源代码并分别解码每个B
。
这是Bash脚本(不保证):
#!/bin/bash
arrKey=$1
input=$2
head -n 1 $input | sed s/.$//
jq -M -c ".$arrKey|.[]" $input | sed s/$/,/
echo "]}"
它确实依赖某些东西,例如非数组问题始终位于第一行。