升压序列化多个对象 [英] Boost Serialization multiple objects

查看:110
本文介绍了升压序列化多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用二进制序列化类的推动作用。我使用的是为了保住附加多个对象到这个文件::追加IOS。我该如何去检索所有存储的对象?

下面是我测试的类,它会尝试多序列化和检索。我有意见的失败地步,我没有得到正确的数据。

 使用命名空间std;
 类数据{
 上市:
双get_latitude()const的{
    返回_latitude;
}双get_longitude()const的{
    返回_longitude;
}无效set_latitude(双_latitude){
    这 - > _latitude = _latitude;
}无效set_longitude(双_longitude){
    这 - > _longitude = _longitude;
}
私人的:
双_latitude;
双_longitude;
友元类的boost ::系列化::访问;
//当类归档对应到一个输出档案中,
//&安培;操作员被定义相似至<&所述;.同样地,当类存档
//是一种类型的输入存档和放大器;操作员被定义相似到大于取代。
模板<类归档和GT;
无效连载(归档和放大器; AR,const的无符号整型版)
{
    AR&安培; _纬度;
    AR&安培; _经度;
}
};类数据测试:公众的CppUnit :: {可是TestFixture
CPPUNIT_TEST_SUITE(数据测试);
CPPUNIT_TEST(testMultipleSaveData);
CPPUNIT_TEST_SUITE_END();上市:无效testMultipleSaveData(){
    数据的数据;
    data.set_latitude(1.0);
    data.set_longitude(2.0);
    SAVEDATA(数据);
    数据secondData;
    secondData.set_latitude(5.0);
    secondData.set_longitude(6.0);
    SAVEDATA(secondData);
    数据returnData;
    数据return2Data;
    {
        //创建和打开输入存档
        性病:: ifstream的IFS(data.dat文件,IOS ::二进制);
        提高::档案:: binary_iarchive IA(IFS);
        //读取存档类状态
        IA>> returnData;
        IA>> return2Data;
        //归档和流闭合析构函数被调用时
    }
    CPPUNIT_ASSERT_EQUAL(data.get_latitude(),returnData.get_latitude());
    CPPUNIT_ASSERT_EQUAL(data.get_longitude(),returnData.get_longitude());
    //失败的下一行
    CPPUNIT_ASSERT_EQUAL(secondData.get_latitude(),return2Data.get_latitude());
    CPPUNIT_ASSERT_EQUAL(secondData.get_longitude(),return2Data.get_longitude());
}无效SAVEDATA(的数据){
    的std :: OFS的ofstream(data.dat文件,内部监督办公室::二元| IOS ::应用程序);
    提高::档案:: binary_oarchive OA(OFS);
    OA<<数据;
} };
 CPPUNIT_TEST_SUITE_REGISTRATION(数据测试);


解决方案

决定增加另一个答案,以免得一塌糊涂。

您的问题是,你序列分离的实例的boost ::存档:: binary_oarchive 升压存档存储在文件开头的一些内部信息(我不会把它叫做一个头,因为升压序列化有单独的头存储版本号),您会收到该信息的两个副本,在文件的开头和您的数据序列化之间。

升压存档不是专为这种用法。即使指定的boost ::存档:: no_header 像:

 的boost ::存档:: text_oarchive的OA(OFS,提振::档案:: no_header);

也无济于事,因为该选项配置另一头,包含版本号。您需要序列化的同一个实例的升压存档

I am serializing a class with boost using binary. I'm using ios::append in order to keep appending multiple objects to this file. How do I go about retrieving all of the objects that are stored?

Here is my test class which tries a multiple serialize and retrieve them. I've comment the failure point where I don't get correct data.

using namespace std;
 class Data {
 public:
double get_latitude() const {
    return _latitude;
}

double get_longitude() const {
    return _longitude;
}

void set_latitude(double _latitude) {
    this->_latitude = _latitude;
}

void set_longitude(double _longitude) {
    this->_longitude = _longitude;
}
private:
double _latitude;
double _longitude;
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<.  Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
    ar & _latitude;
    ar & _longitude;
}
};

class DataTest: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( DataTest);
CPPUNIT_TEST(testMultipleSaveData);
CPPUNIT_TEST_SUITE_END();

public:

void testMultipleSaveData() {
    Data data;
    data.set_latitude(1.0);
    data.set_longitude(2.0);
    saveData(data);
    Data secondData;
    secondData.set_latitude(5.0);
    secondData.set_longitude(6.0);
    saveData(secondData);
    Data returnData;
    Data return2Data;
    {
        // create and open an archive for input
        std::ifstream ifs("data.dat", ios::binary);
        boost::archive::binary_iarchive ia(ifs);
        // read class state from archive
        ia >> returnData;
        ia >> return2Data;
        // archive and stream closed when destructors are called
    }
    CPPUNIT_ASSERT_EQUAL(data.get_latitude(), returnData.get_latitude());
    CPPUNIT_ASSERT_EQUAL(data.get_longitude(), returnData.get_longitude());
    //Failure on next line
    CPPUNIT_ASSERT_EQUAL(secondData.get_latitude(), return2Data.get_latitude());
    CPPUNIT_ASSERT_EQUAL(secondData.get_longitude(), return2Data.get_longitude());
}

void saveData(Data data) {
    std::ofstream ofs("data.dat", ios::binary | ios::app);
    boost::archive::binary_oarchive oa(ofs);
    oa << data;
}

 };
 CPPUNIT_TEST_SUITE_REGISTRATION( DataTest);

解决方案

Decided to add another answer to avoid complete mess.

Your problem is that you serialize to separate instances of boost::archive::binary_oarchive. Boost Archive stores some internal info at the beginning of the file (I won't call it a header because Boost Serialization has separate header to store version number), and you receive two copies of this info, at the beginning of the file and between your Data serializations.

Boost Archive wasn't designed for such usage. Even specifying boost::archive::no_header like in:

boost::archive::text_oarchive oa(ofs, boost::archive::no_header);

doesn't help, because this option configures another header, that contains version number. You need to serialize to the same instance of Boost Archive.

这篇关于升压序列化多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆