代码之家  ›  专栏  ›  技术社区  ›  Pejman

存储flatbuffers对象的非根表以供以后反序列化

  •  0
  • Pejman  · 技术社区  · 6 年前

    this stack overflow question ):

    table Foo {
        ...
    }
    table Bar {
        value:[Foo];
    }
    root_type Bar;
    

    假设 Foo 典型对象中的s是重要的,因此我们希望避免修改schema以使 这个 root_type .

    脚本:

    C++客户端序列化一个适当的平面缓冲区对象,并将其张贴到另一个组件(NoDEJS后端),该组件部分反序列化对象并存储表示每个对象的二进制文件。 在作为单独文档的数据库中:

    const buf = new flatbuffers.ByteBuffer(req.body)
    const bar = fbs.Bar.getRootAsBar(buf)
    for (let i = 0; i < bar.valueLength(); i++) {
      const foo = bar.value(i)
      let item = {
        'raw': foo.bb.bytes_ // <-- primary suspect
      }
      // ... store `item` as an individual entity (mongodb doc)
    }
    

    稍后,第三个组件获取存储在mongodb文档的“raw”键中的二进制数据,并尝试将其反序列化为

    auto mongoCol = db.collection("results");
    auto mongoResult = mongoCol.find_one(
        bsoncxx::builder::stream::document{}
        << "_id" << oid << bsoncxx::builder::stream::finalize);
    // ...check that mongoResult is not null
    const auto result = mongoResult->view();
    const auto& binary = result["raw"].get_binary();
    std::string content((const char*)binary.bytes, binary.size);
    const auto& foo = flatbuffers::GetRoot<fbs::Foo>(content.c_str());
    

    问题是:

    但指针是 foo 不指向预期的数据和上的任何操作

    怀疑:

    我推测根本原因是存储在数据库中的二进制文件根据原始消息使用偏移量。因此,它本身的原始格式本质上是无效的,在插入数据库之前应该重新调整偏移量。但是我没有看到任何flatbuffers函数API来重新调整偏移量?

    我怀疑它与偏移量有关的原因是,如果我们做出妥协,在每个条向量中使用一个Foo元素发布更小的flatbuffers对象(并更改后端代码以存储 bar.bb.bytes 在里面 raw 相反)。

    无论如何,是否有可能获取一个更大的、构造正确的flatbuffers二进制文件的一部分 表示所需的表并自行反序列化?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Aardappel    6 年前

    不能简单地从较大的FlatBuffer字节中复制子表,因为这些数据不一定是连续的。最好的解决办法是 Bar 存储a [FooBuffer] table FooBuffer { buf:[byte] (nested_flatbuffer: Foo) } . 当你构建其中一个时,你构建每个 Foo 变成自己的 FlatBufferBuilder 然后将生成的字节存储在父级中。当你需要储存 这就变成了一个简单的复制品。