最后,经过多次努力,我找到了一种序列化和反序列化std::map<int,map<int,structute values>
的方法,并且能够打印这些值。
请您澄清我对以下代码的疑虑
void serialize(archive & ar, const unsigned int version)
函数是否用于序列化和反序列化我们是否可以为每个类和结构中的序列化和反序列化分别设置函数
- 醇>
是否也可以使用相同的功能来创建xml,或者是为xml提供单独的序列化和反序列化功能的简洁方法
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <map>
#include <boost/serialization/map.hpp>
struct values
{
std::string name;
std::string sex;
values():name("dummy"),sex("dummy"){} ;
template<class archive>
void serialize(archive & ar, const unsigned int version)
{
ar & name ;
ar & sex ;
}
};
class Myclass
{
public:
Myclass()
{
values val1;
e_group.insert( std::make_pair(1,val1) ) ;
e_group.insert( std::make_pair(2,val1) ) ;
p_group.insert( std::make_pair(1,e_group) ) ;
p_group.insert( std::make_pair(2,e_group) ) ;
}
template<class archive>
void serialize(archive & ar, const unsigned int version)
{
ar & e_group ;
ar & p_group;
}
typedef std::map<int,values> groups;
typedef std::map<int,groups> Pgroups;
groups e_group;
Pgroups p_group;
};
int main() {
char buf[256];
Myclass obj;
std::stringstream os(std::ios_base::binary| std::ios_base::out| std::ios_base::in);
{
boost::archive::binary_oarchive oa(os, boost::archive::no_header);
oa << obj ;
// oa << make_binary_object(&e_group, sizeof(e_group));
}
//print binary data
std::string data = os.str();
for (uint8_t ch : data) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch) << " ";
}
Myclass t2;
{
memcpy(buf, os.str().data(), os.str().length());
if(memcmp(buf, os.str().data(), os.str().length()) != 0)
printf("memcpy error\n");
std::stringstream is(std::string(buf, buf+os.str().length() ), std::ios_base::binary| std::ios_base::out| std::ios_base::in);
boost::archive::binary_iarchive ia(is, boost::archive::no_header);
ia >> t2;
}
for(auto &i:t2.p_group){
std::cout<<"\n"<<i.first<<"\n";
for(auto &j:i.second){
std::cout<<"\t"<<j.first<<"\t"<<j.second.name<<"\t"<<j.second.sex<<"\n";
}
}
return 0;
}
更新:我更新了richard的代码并添加了一个去除二进制文件
的函数
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <map>
#include <boost/serialization/map.hpp>
#include <boost/serialization/split_member.hpp>
struct values
{
std::string name;
std::string sex;
values():name("dummy"),sex("dummy"){} ;
BOOST_SERIALIZATION_SPLIT_MEMBER();
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
// note, version is always the latest when saving
ar & BOOST_SERIALIZATION_NVP(name);
ar & BOOST_SERIALIZATION_NVP(sex);
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(name);
ar & BOOST_SERIALIZATION_NVP(sex);
}
};
class Myclass
{
public:
Myclass()
{
values val1;
e_group.insert( std::make_pair(1,val1) ) ;
e_group.insert( std::make_pair(2,val1) ) ;
p_group.insert( std::make_pair(1,e_group) ) ;
p_group.insert( std::make_pair(2,e_group) ) ;
}
BOOST_SERIALIZATION_SPLIT_MEMBER();
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
// note, version is always the latest when saving
ar & BOOST_SERIALIZATION_NVP(e_group);
ar & BOOST_SERIALIZATION_NVP(p_group);
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(e_group);
ar & BOOST_SERIALIZATION_NVP(p_group);
}
typedef std::map<int,values> groups;
typedef std::map<int,groups> Pgroups;
groups e_group;
Pgroups p_group;
};
template<class Archive, class Object>
std::string serialise_to_string(Object const& assetlist)
{
auto os = std::ostringstream(std::ios::binary);
Archive arch { os, boost::archive::no_header };
arch << BOOST_SERIALIZATION_NVP(assetlist);
return os.str();
};
std::ostream& dump(std::ostream& os, std::string const& s)
{
const char *sep = "";
for (uint8_t ch : s) {
std::cout << sep << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch);
sep = " ";
}
return os;
}
template<class Archive , class Object>
void deserialise_to_obj(std::string const &s1,Object &outObj)
{
std::stringstream is( s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
Archive arch { is, boost::archive::no_header };
arch >> BOOST_SERIALIZATION_NVP(outObj);
};
int main() {
Myclass obj ;
std::string s1 = serialise_to_string<boost::archive::binary_oarchive>(obj);
dump(std::cout, s1) << std::endl << std::endl;
auto s2 = serialise_to_string<boost::archive::xml_oarchive>(obj);
//Save xml to a file
std::ofstream ofs("output.xml");
ofs << s2 << std::endl << std::endl;
//Deserialize the binary data to object
Myclass outObj;
deserialise_to_obj<boost::archive::binary_iarchive>(s1,outObj);
//Print the object
for(auto &i:outObj.p_group){
std::cout<<"\n"<<i.first<<"\n";
for(auto &j:i.second){
std::cout<<"\t"<<j.first<<"\t"<<j.second.name<<"\t"<<j.second.sex<<"\n";
}
}
}
使用coliru
编译的代码请建议。如果我的方法有误,请告诉我
我要感谢@sehe和@richard帮我提升。
由于 特加斯
答案 0 :(得分:2)
首先,不要这样做:
memcpy(buf, os.str().data(), os.str().length());
if(memcmp(buf, os.str().data(), os.str().length()) != 0)
那只是创建了4个单独的字符串副本。
现在问题:
用于序列化和反序列化的void serialize(archive&amp; ar,const unsigned int version)函数
是
我们可以为每个类和结构中的序列化和反序列化分别设置函数
是
是否可以使用相同的功能来创建xml,或者是为xml提供单独的序列化和反序列化功能的简洁方法
是
您想要xml_oarchive
以及宏BOOST_SERIALIZATION_SPLIT_MEMBER
和BOOST_SERIALIZATION_NVP
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <map>
#include <boost/serialization/map.hpp>
#include <boost/serialization/split_member.hpp>
struct values
{
std::string name;
std::string sex;
values():name("dummy"),sex("dummy"){} ;
BOOST_SERIALIZATION_SPLIT_MEMBER();
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
// note, version is always the latest when saving
ar & BOOST_SERIALIZATION_NVP(name);
ar & BOOST_SERIALIZATION_NVP(sex);
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(name);
ar & BOOST_SERIALIZATION_NVP(sex);
}
};
class Myclass
{
public:
Myclass()
{
values val1;
e_group.insert( std::make_pair(1,val1) ) ;
e_group.insert( std::make_pair(2,val1) ) ;
p_group.insert( std::make_pair(1,e_group) ) ;
p_group.insert( std::make_pair(2,e_group) ) ;
}
BOOST_SERIALIZATION_SPLIT_MEMBER();
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
// note, version is always the latest when saving
ar & BOOST_SERIALIZATION_NVP(e_group);
ar & BOOST_SERIALIZATION_NVP(p_group);
}
template<class Archive>
void load(Archive & ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(e_group);
ar & BOOST_SERIALIZATION_NVP(p_group);
}
typedef std::map<int,values> groups;
typedef std::map<int,groups> Pgroups;
groups e_group;
Pgroups p_group;
};
template<class Archive, class Object>
std::string serialise_to_string(Object const& o)
{
auto os = std::ostringstream(std::ios::binary);
Archive arch { os, boost::archive::no_header };
arch << BOOST_SERIALIZATION_NVP(o);
return os.str();
};
std::ostream& dump(std::ostream& os, std::string const& s)
{
const char *sep = "";
for (uint8_t ch : s) {
std::cout << sep << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(ch);
sep = " ";
}
return os;
}
int main() {
char buf[256];
Myclass obj;
auto s1 = serialise_to_string<boost::archive::binary_oarchive>(obj);
dump(std::cout, s1) << std::endl << std::endl;
auto s2 = serialise_to_string<boost::archive::xml_oarchive>(obj);
std::cout<< s2 << std::endl << std::endl;
return 0;
}
示例输出:
00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79 02 00 00 00 05 00 00 00 00 00 00 00 64 75 6d 6d 79 05 00 00 00 00 00 00 00 64 75 6d 6d 79
<o class_id="0" tracking_level="0" version="0">
<e_group class_id="1" tracking_level="0" version="0">
<count>2</count>
<item_version>0</item_version>
<item class_id="2" tracking_level="0" version="0">
<first>1</first>
<second class_id="3" tracking_level="0" version="0">
<name>dummy</name>
<sex>dummy</sex>
</second>
</item>
<item>
<first>2</first>
<second>
<name>dummy</name>
<sex>dummy</sex>
</second>
</item>
</e_group>
<p_group class_id="4" tracking_level="0" version="0">
<count>2</count>
<item_version>0</item_version>
<item class_id="5" tracking_level="0" version="0">
<first>1</first>
<second>
<count>2</count>
<item_version>0</item_version>
<item>
<first>1</first>
<second>
<name>dummy</name>
<sex>dummy</sex>
</second>
</item>
<item>
<first>2</first>
<second>
<name>dummy</name>
<sex>dummy</sex>
</second>
</item>
</second>
</item>
<item>
<first>2</first>
<second>
<count>2</count>
<item_version>0</item_version>
<item>
<first>1</first>
<second>
<name>dummy</name>
<sex>dummy</sex>
</second>
</item>
<item>
<first>2</first>
<second>
<name>dummy</name>
<sex>dummy</sex>
</second>
</item>
</second>
</item>
</p_group>
</o>