【问题标题】:FlatBuffers: Write to and read from binary file?FlatBuffers:写入和读取二进制文件?
【发布时间】:2014-11-06 17:29:24
【问题描述】:

我对 C++ 和 Google FlatBuffers 中的文件流有基本的了解。 Schema 文件非常简单,也创建了一个缓冲区并读取 从缓冲区指针。我不明白的是如何将多个缓冲区保存到一个二进制文件中,然后将该二进制文件读取到 获取任意随机缓冲区。

这是一个带有两个浮点数组的简单 Schema:

table Car {
    field_a:[float];
    field_b:[float];
}

.

建立缓冲区的函数(虽然没有保存文件):

bool save_flatbuf(string file_path, vector<double> vec_a, vector<double> vec_b) {
    flatbuffers::FlatBufferBuilder builder;

    auto vec_floats_a = builder.CreateVector(vec_a, vec_a.size());
    auto vec_floats_b = builder.CreateVector(vec_b, vec_b.size());

    auto mloc = CreateCar(builder, &vec_floats_a, &vec_floats_b);

    builder.Finish(mloc);

    // How to save it into a binary file with a list of "Cars"?
}

.

还有一个从二进制文件读取缓冲区后读取缓冲区的函数(不读取文件):

bool read_flatbuf(string file_path) {

    // How to get the buffer pointer to a "Car" from a binary file with a "list of Cars" ? .

    vector<double> final_vec_a;
    vector<double> final_vec_b;

    auto car = GetCar(buffer_pointer);

    auto fa = car->field_a();
    auto fb = car->field_b();

    final_vec_a.resize(fa->size());
    for (int i = 0; i < fa->size(); i++) {
        final_vec_a[i] = fa->Get(i);
    }

    final_vec_b.resize(fb->size());
    for (int i = 0; i < fb->size(); i++) {
        final_vec_b[i] = fb->Get(i);
    }
}

不确定访问缓冲区信息的方式是否正确。比如获取数组字段长度的方法。

欢迎使用文件交互的代码示例(在一个文件中写入/读取多个缓冲区)。

【问题讨论】:

  • +1 我在文档中找不到任何关于此的内容。 (FlatBufferBuilder 没有 API 参考,这让我抓狂。)

标签: c++ serialization fstream binaryfiles flatbuffers


【解决方案1】:

将汽车列表添加到您的架构中的最佳方法:

table Garage {
  cars:[Car];
}

然后您可以收集多个汽车偏移量(来自CreateCar),对它们调用CreateVector,对其调用CreateGarage,然后将其结果提供给Finish

要阅读,同样从GetGarage(buffer_pointer)开始。

【讨论】:

    【解决方案2】:

    我的解决方案是添加额外的尺寸信息。

    给作家 ::

    for (item : flatbuffer_list) {
       int size = item.GetSize();
       write (file, &size, sizeof(size));
       write (file, item.GetBufferPointer(), item.GetSize());
    }
    

    给读者::

    while(!eof(file)) {
       int size;
       read (file, &size, sizeof(size));
       read (file, buffer, size);
       auto item = GetItem(buffer);
    }
    

    【讨论】:

      【解决方案3】:

      将缓冲区存储到二进制文件的快速参考。

      builder.Finish(mloc);
      uint8_t *buf = builder.GetBufferPointer();
      int size = builder.GetSize();
      
      std::ofstream ofile("data.bin", std::ios::binary);
      ofile.write((char *)buf, size);
      ofile.close();
      

      从文件中读取:

      const std::string inputFile = "data.bin";
      std::ifstream infile(inputFile, std::ios_base::binary);
      std::vector<char> buffer( std::istreambuf_iterator<char>(infile),
                            std::istreambuf_iterator<char>());
      

      【讨论】:

      • infile在读取文件时的声明是什么?
      【解决方案4】:

      “欢迎使用文件交互的代码示例(在一个文件中写入/读取多个缓冲区)。”

      我在测试游戏中使用这样的 fbs 和 json。 (生成到out_cpp文件夹:gamedata.bin、gamedata.h)

      flatc -b -c -o out_cpp gamedata.fbs gamedata.json

      我第一次发现这个 flatbuffers 示例非常有用。

      https://github.com/gene-hightower/fb

      在我的情况下,除非您使用 flatbuffers::LoadFile() 而不是提供的示例 load_file(),否则 git 示例无法正常工作。

      【讨论】:

      • 回购链接已损坏。
      猜你喜欢
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 2015-06-16
      • 2010-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多