Protobuf Net 和从二进制文件存储/检索数据块

Posted

技术标签:

【中文标题】Protobuf Net 和从二进制文件存储/检索数据块【英文标题】:Protobuf Net and storing/retrieving data blobs to/from binary file 【发布时间】:2012-06-08 06:06:26 【问题描述】:

我想弄清楚是否可以使用 protobuf-net 来存储和检索以下序列化数据结构:

我每天有大约 200,000 个大小为 16 字节的对象(该对象包含一个 long 和两个浮点类型值,8 字节加上 2 * 4 字节),我喜欢将它们存储在二进制文件中。此类对象的检索将仅按一整天进行,例如,我想请求 2012 年 4 月 1 日至 2012 年 4 月 6 日之间的对象,这些对象应该从 4 月 1 日开始读取,然后是 4 月 2 日,... 4 月 6 日。一个要求是访问需要是随机的,这意味着,该文件可能包含从 2010 年到 2012 年 6 月的数据,但我可能只想检索 2012 年 4 月 1 日到 4 月 6 日之间的元素,而不必从一开始就读取所有元素。

我目前将数据存储为按 DateTimeTick 顺序的连续字节数组,但不考虑新一天的开始或结束时间。如果我可以使用 protbuf-net 将数据作为 IEnumerable 的全天“blob”流式传输,那就太棒了。那可能吗?我正在考虑为使用 protobuf-net 序列化的每一天存储一个 IEnumerable 或 List,但不知道以后如何随机访问特定列表?有什么想法或建议吗?谢谢

【问题讨论】:

【参考方案1】:

这不是 protobuf-net 的典型用例,虽然我怀疑可以以这种方式使用它,但它不会是我本能地尝试这样做。如果关键要求是按天拆分,那么使用多个文件将是一个明显的选择。或者,调整您现有的文件格式以包括(每天)日期戳和当天数据的大小 - 然后您可以使用FileStream.Position 属性在一整天内向前跳过。

protobuf-net 确实有流式传输和跳过 API,或者如果您不想涉及核心序列化程序,则可以使用原始“阅读器”API,但是:我不确定这是否会大量帮助你。

坦率地说,由于(在您当前的流程中)每个块的大小都是固定的,您还可以使用二分搜索(可能对凝视位置使用线性插值)来寻找正确的时间。

【讨论】:

感谢您的 cmets。如果我将每一天都存储在一个单独的文件中,您会建议将对象存储为使用 protobuf-net 序列化的 List 或 IEnumerable,还是简单地存储和检索给定日期的所有原始字节数组会更快? @Freddy 如果你有一些有用的东西,我会坚持下去。 protobuf-net 是高效的,但仍需要进行一定程度的处理,因为格式更加结构化和灵活。它还希望在输出中添加一些(非常简洁,即通常每个字段 1 个字节)标头。在您描述的情况下,数据非常简单(即非结构化,具有嵌套/内部数据以及可预测的布局)我不确定 protobuf-net 是否会为您购买任何东西。它擅长处理更通用的对象序列化,这可能很复杂,需要...... ...随着时间的推移可扩展,以便人们可以轻松地“版本化”数据(即在某些时候添加一个新字段),或处理复杂的对象树(A 有一个 B 的列表,每个其中有一个C和一个D,以及各个级别的各种其他领域)。

以上是关于Protobuf Net 和从二进制文件存储/检索数据块的主要内容,如果未能解决你的问题,请参考以下文章

在 MFC 中从二进制文件加载图像

将核心数据文件从二进制转换为 XML

将 protobuf 字节类型存储在二进制文件中

从二进制文件创建 Numpy 数组的有效方法

用 C 语言从二进制文件中读取位

使用 ifstream 从二进制文件中读取 4 个字节