scala 将JSON文件转储为二进制文件的形式

f0ofjuux  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(79)

我有一个非常大的json文件,可能接近1.5GB,

[
  {
    "a": 123,
    "b": 143,
    "c": "111",
    "d": 0,
    "e": 0
  },
  {
    "a": 1455,
    "b": 1899,
    "c": "1334",
    "d": 0,
    "e": 0
  }
]

字符串
所以我想找到一种方法将其转换为二进制格式,并有效地读取这个json文件中的数据。我能知道使用Scala实现这一点的方法吗?

chhqkbe1

chhqkbe11#

我将给予一个可能的答案,然后详细介绍选择序列化格式的细节,希望它可以作为您了解全局的指导。
存在多种二进制序列化格式,每种格式都有自己的优点和缺点,这就是为什么给您“一个正确答案”甚至不值得尝试的原因。
我可以给你给予一个建议,让你开始,是评估Apache Avro,一个广泛的二进制格式,它经常与Apache Kafka和一般的大型数据处理系统。
下面是一个简短的例子,说明如何使用Circe解析原始JSON文件,然后使用avro4s序列化到Avro:

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

final case class Item(a: Int, b: Int, c: String, d: Int, e: Int)

val items = parse(json).flatMap(_.as[Vector[Item]]).toTry.get

import com.sksamuel.avro4s._

val schema = AvroSchema[Item]
val baos = new java.io.ByteArrayOutputStream()
val os = AvroOutputStream.data[Item].to(baos).build()
os.write(items)
os.flush()
os.close()
baos.close()

字符串
你可以使用这个代码here on Scastie。注意:
1.我将json作为lazy val放在操场的最后,因为Avro需要将数据模式与数据本身一起存储,这意味着对于一些对象,自描述JSON格式实际上更紧凑,因此我需要包含更多内容以确保我没有歪曲该格式的优点和缺点
1.在这里,我将序列化为一个字节数组,以便我链接到的在线游戏场给予您使用二进制格式可以实现的节省,实际上,您很可能会写入某种持久存储
如上所述,上面的是一个可能的答案。实际上,选择数据序列化格式并不简单,需要很好地理解所涉及的权衡,考虑到一旦选择了一种格式,根据所涉及的系统,迁移它可能是一个漫长,困难和风险的操作。
如果你感兴趣的只是节省空间,你可能想看看简单地压缩JSON是否对你有用,知道这将把节省的空间转化为计算时间,否则可能会花费在其他方面。如果文件的结构是非常可预测的,压缩的JSON文件可能能够与压缩的二进制文件竞争。JSON在工具的可用性和检查文件本身,除了文本编辑器之外没有任何专门的工具。
如果你仍然确信你想转移到二进制序列化格式,那么有很多存在的序列化格式都是出于特定的需要,你可能想一个接一个地研究它们,以评估它们是否适合你的项目。我将列举一些最广泛使用的序列化格式:

  • Avro
  • Protocol Buffers
  • 节俭
  • Flatbuffers
  • 普罗托船长
  • BSON
  • parquet
  • CBOR
  • MessagePack

This page on Wikipedia可能会让你对每一个特性有一个大致的了解。你可能想问自己的几个问题是:

  • 对于我的团队使用的语言,有什么样的支持?
  • 一般如何使用格式,为什么?
  • 格式如何允许我考虑模式演变和向后/向前兼容性?
  • 格式是自描述的还是需要引用外部存储的模式?

相关问题