You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NDJSON的替代方案有哪些?求满足特定需求的磁盘序列化格式

推荐的磁盘序列化格式及实现方案

1. MessagePack + 长度前缀

  • 满足条件:支持UTF-8/二进制、无schema、具备Node/Rust实现
  • 单文件多消息实现:在每个MessagePack消息前添加固定长度前缀(比如4字节大端整数,标识后续消息的字节长度),通过前缀分隔不同消息。
    • Go写入示例:
      import "github.com/vmihailenco/msgpack/v5"
      import "encoding/binary"
      
      func writeMsg(w io.Writer, data any) error {
          b, err := msgpack.Marshal(data)
          if err != nil {
              return err
          }
          // 写入4字节长度前缀
          if err := binary.Write(w, binary.BigEndian, uint32(len(b))); err != nil {
              return err
          }
          _, err = w.Write(b)
          return err
      }
      
    • Go读取示例:
      func readMsg(r io.Reader, v any) error {
          var length uint32
          if err := binary.Read(r, binary.BigEndian, &length); err != nil {
              return err
          }
          b := make([]byte, length)
          _, err := io.ReadFull(r, b)
          if err != nil {
              return err
          }
          return msgpack.Unmarshal(b, v)
      }
      
  • 优势:序列化体积小、性能优异,生态成熟稳定,Node(msgpack-lite)和Rust(rmp-serde)均有可靠实现。

2. CBOR 序列(CBOR Sequence, RFC 8742)

  • 满足条件:支持UTF-8/二进制、原生支持多消息、无schema、具备Node/Rust实现
  • 你提到CBOR本身支持序列但Go中没找到方法,实际上Go的fxamacker/cbor库原生支持CBOR序列的读写,无需手动处理分隔逻辑:
    • Go写入示例:
      import "github.com/fxamacker/cbor/v2"
      
      func writeCBORSeq(w io.Writer, msgs []any) error {
          enc, err := cbor.NewEncoder(w, cbor.EncOptions{Sequence: cbor.SeqIndefinite})
          if err != nil {
              return err
          }
          for _, msg := range msgs {
              if err := enc.Encode(msg); err != nil {
                  return err
              }
          }
          return enc.Close() // 结束序列
      }
      
    • Go读取示例:
      func readCBORSeq(r io.Reader) ([]any, error) {
          dec, err := cbor.NewDecoder(r, cbor.DecOptions{Sequence: cbor.SeqIndefinite})
          if err != nil {
              return nil, err
          }
          var msgs []any
          var msg any
          for dec.Decode(&msg) == nil {
              msgs = append(msgs, msg)
              msg = nil
          }
          return msgs, nil
      }
      
  • 优势:原生标准支持多消息,无需手动加前缀,扩展性比MessagePack更强,Node(cbor)和Rust(serde_cbor)都有完善工具链。

3. FlatBuffers(无schema模式)

  • 满足条件:支持二进制、无schema(通过反射解析)、具备Node/Rust实现
  • 单文件多消息实现:用长度前缀分隔每个FlatBuffer消息,Go中可通过github.com/google/flatbuffers/go库的GetRootAs方法反射解析无schema的FlatBuffer数据。
  • 优势:序列化后无需完整解析即可直接访问字段,性能极高,但上手成本略高于前两种方案。

与ASN.1的对比

ASN.1的编码格式(如BER/DER)较为繁琐,生态活跃度远不如MessagePack/CBOR,序列化后的体积通常更大。上述方案在满足你需求的前提下,具备更轻量、性能更优、工具链更完善的特点。

内容的提问来源于stack exchange,提问作者Mascarpone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:35:18