使用 sstream 中的提升binary_iarchive进行序列化和反序列化
serialize and deserialise using boost binary_iarchive from sstream
最后,经过一番挣扎,我找到了一种序列化和反序列化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 errorn");
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;
}
更新:我更新了理查德的代码并添加了一个函数来取消二进制文件
#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帮助我提升。
谢谢光辉
首先,不要这样做:
memcpy(buf, os.str().data(), os.str().length());
if(memcmp(buf, os.str().data(), os.str().length()) != 0)
这只是创建了一个字符串的 4 个独立副本。
现在的问题:
是否用于序列化和反序列化的void 序列化(存档和 ar,const 无符号 int 版本(函数
是的
我们可以在每个类和结构中为序列化和反序列化提供单独的函数吗?
是的
同样的函数也可以用于创建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>
相关文章:
- 如何在C++中序列化结构数据
- 序列化,没有库的整数,得到奇怪的结果
- 如何知道QDataStream不能反序列化某些内容
- 如何使用Python从C++中读取谷物序列化数据
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- 带有Protobuf序列化的C++Hazelcast:字符串不是UTF-8格式的
- 自定义对象的dlib序列化在gcc中失败
- C++boost序列化多态性问题
- 增强基于 XML class_id的反序列化
- 提升反序列化对象具有 nan 或 -nan 值
- 在 cpp 中的平面缓冲区中序列化对象
- 每次进行继承时都需要提升::序列化::base_object吗?
- 如何在 c++ 非托管代码中反序列化 byte[] 的 json 字符串?
- 提升序列化 1:73 的向后兼容性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 为什么 nlohmann/json 序列化 "null" 而不是在 double 上"0"?
- 如何反序列化数组?
- 如何使用提升序列化?
- 序列化多晶型接口
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?