【问题标题】:How to perform partial deserialization of std::map by C++ boost::serialization如何通过 C++ boost::serialization 执行 std::map 的部分反序列化
【发布时间】:2012-06-23 17:20:08
【问题描述】:

我有一个高度格式化的文件,其中包含我经常使用的大量数据,因此我将其存储到 std::map 并使用 boost::serialization 库对其进行序列化。序列化代码如下:

boost::iostreams::filtering_ostream ofs {};
ofs.push (boost::iostreams::zlib_compressor ());
ofs.push (boost::iostreams::file_sink (file_name));
boost::archive::binary_oarchive oa {ofs};
oa << my_map;

但每次我可能只需要地图的一部分,比如某个键值对。所以我想知道我是否可以从文件中部分反序列化地图并只检索我指定的对?这样我就不必将整个文件读入内存。

【问题讨论】:

    标签: c++ serialization boost


    【解决方案1】:

    您可以为您的数据创建索引,但在存在压缩的情况下使用起来会有些困难。如果您的数据文件未压缩,并且说每条记录都在一行上,那么您可以创建一个索引,在其中将每行的连续 offsets 存储在固定宽度的记录中,比如无符号 64 位数字.

    要找到第 5112 行,您需要打开索引,查找 5112 * 8,然后读取两个 uint64_ts,例如 ab。然后你打开你的数据文件,寻找a并读取b - a字节,这是你的记录。

    如果数据被压缩,您必须查看压缩库,看看它是否允许您仅部分解压缩包含字节 [a, b) 的文件区域。

    【讨论】:

    • 感谢您的回复,Kerrek。非常有帮助!不幸的是,以固定宽度的模式存储我的数据是不切实际的。我想我必须将每个数据的大小存储在 gzip 的标头中。然后我必须为过滤流定义我自己的压缩器......这超出了我的能力。而且您提到的“压缩”方法也需要我这样做:-(如果我错了请纠正我!感谢您的回复!
    • @bowhan:为了清楚起见,您的 data 不会是固定宽度的,只有您的 index。您必须建立一次索引,这很慢,但之后您基本上可以随机访问您的记录。
    • @Kerrer:我明白你的意思了!对不起我的误解。但是我仍然不知道如何做这个索引,因为地图的键有命令。例如,我想检索 key1 的值,但我不知道 key1 的索引在索引文件中的位置,除非我创建索引的索引。所以我认为文本索引文件会更直接。实际上,通过随机访问,我感觉失去了地图序列化的感觉。我可以为原始数据创建一个随机访问文件并每次都读取我想要的片段而不构建地图吗?如果我犯了任何错误,请纠正我!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2011-05-15
    • 2011-09-21
    • 1970-01-01
    • 2013-12-09
    • 1970-01-01
    • 2018-02-02
    相关资源
    最近更新 更多