AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
## 序列化定义 在编写程序过程中往往需要将某些数据存储到内存中,然后将其写入文件或通过网络传输到另一台计算机实现通信。这个将数据转化成能够存储或传输格式的过程被称为序列化,而其逆过程则被称为反序列化。 详细来说,序列化是将对象实例的状态转换为可存储或传输格式的过程,反序列化是依据存储或传输的内容重构对象,两者结合起来,能轻松进行数据存储和数据传输。比如,序列化一个对象,然后使用http通过Internet在client和server之间传输。简言之: * 序列化:将对象变成字节流。 * 反序列化:从字节流恢复成原来的对象。 ## 序列化实现 在C++中,常用的序列化工具有Json,XML和protobuf等,但用这些工具的时候都需要依赖相应的库,相对来说比较麻烦。为了理解序列化过程和可以不依赖其他库实现一些简单的序列化功能,用C++实现一个简单的序列化工具,代码只有一百多行。实现参考[https://github.com/button-chen/buttonrpc\_cpp14](https://github.com/button-chen/buttonrpc_cpp14) ``` /** * 序列化反序列化 * 仅支持原生类型的数据结构,不支持含有指针的数据结构 */ #ifndef SERIALIZER_H #define SERIALIZER_H #include <vector> #include <algorithm> // 存储数据流的容器 class StreamBuffer : public std::vector<char> { public: StreamBuffer() : curpos_(0) {} StreamBuffer(const char* s, size_t len) : curpos_(0) { insert(begin(), s, s + len); } const char* data() { return &(*this)[0]; } const char* curdata() { return &(*this)[curpos_]; } size_t cursize() const { return size() - curpos_; } bool eof() const { return curpos_ >= size(); } void offset(int k) { curpos_ += k; } void input(const char* s, size_t len) { insert(end(), s, s + len); } void reset() { curpos_ = 0; } private: size_t curpos_; }; class Serializer { public: enum ByteOrder { BigEndian, // 大端 LittleEndian // 小端 }; public: Serializer() : byteOrder_(LittleEndian) {} Serializer(StreamBuffer s, int byteOrder = LittleEndian) : streamBuffer_(s), byteOrder_(byteOrder) {} template <typename T> void input_type(T t); template <typename T> void output_type(T& t); template<typename Tuple, std::size_t Id> void getv(Serializer& ds, Tuple& t) { ds >> std::get<Id>(t); } void reset(){ streamBuffer_.reset(); } void clear() { streamBuffer_.clear(); reset(); } void input(const char* data, int len) { streamBuffer_.input(data, len); } template<typename Tuple, std::size_t... I> Tuple get_tuple(std::index_sequence<I...>) { Tuple t; ((getv<Tuple, I>(*this, t)), ...); return t; } template<typename T> Serializer& operator >> (T& i) { output_type(i); return *this; } template<typename T> Serializer& operator << (T i) { input_type(i); return *this; } const char* data() { return streamBuffer_.curdata(); } size_t size() const { return streamBuffer_.cursize(); } private: void byte_order(char* s, int len) { if (byteOrder_ == BigEndian) std::reverse(s, s + len); } private: int byteOrder_; StreamBuffer streamBuffer_; }; template <typename T> inline void Serializer::input_type(T t) { int len = sizeof(T); char* d = new char[len]; const char* p = reinterpret_cast<const char*>(&t); memcpy(d, p, len); byte_order(d, len); streamBuffer_.input(d, len); delete[] d; } // 偏特化 template <> inline void Serializer::input_type(std::string t) { // 先存入字符串长度 uint16_t len = t.size(); char* p = reinterpret_cast<char*>(&len); byte_order(p, sizeof(uint16_t)); streamBuffer_.input(p, sizeof(uint16_t)); // 存入字符串 if (len == 0) return; char* d = new char[len]; memcpy(d, t.data(), len); byte_order(d, len); streamBuffer_.input(d, len); delete[] d; } template<> inline void Serializer::input_type(const char* in) { input_type<std::string>(std::string(in)); } template <typename T> inline void Serializer::output_type(T& t) { int len = sizeof(T); char* d = new char[len]; if (!streamBuffer_.eof()) { memcpy(d, streamBuffer_.curdata(), len); streamBuffer_.offset(len); byte_order(d, len); t = *reinterpret_cast<T*>(&d[0]); } delete[] d; } // 偏特化 template <> inline void Serializer::output_type(std::string& t) { // 先取字符串长度 int strlen = sizeof(uint16_t); char* d = new char[strlen]; memcpy(d, streamBuffer_.curdata(), strlen); byte_order(d, strlen); streamBuffer_.offset(strlen); int len = *reinterpret_cast<uint16_t*>(&d[0]); delete[] d; // 再取字符串 if (len == 0) return; t.insert(t.begin(), streamBuffer_.curdata(), streamBuffer_.curdata() + len); streamBuffer_.offset(len); } #endif ``` ## 验证 ``` #include <iostream> #include "serializer.h" using namespace std; struct S { S() {} S(int i, float f) : a(i), b(f) {} int a; float b; friend ostream &operator<<(ostream &os, const S &s); }; ostream &operator<<(ostream &os, const S &s) { return os << s.a << ", " << s.b; } int main() { Serializer serializer; string str = "abcdef"; int n = 10; S s(7, 11.2); serializer.input_type(str); serializer.input_type(n); serializer.input_type(s); string got_str; int got_n; S got_s; serializer.output_type(got_str); serializer.output_type(got_n); serializer.output_type(got_s); cout << "got_str: " << got_str << endl; cout << "got_n: " << got_n << endl; cout << "got_s: " << got_s << endl; } ``` 输出结果: ``` got_str: abcdef got_n: 10 got_s: 7, 11.2 ```