日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

序列化和反序列化实现

發布時間:2023/11/27 生活经验 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 序列化和反序列化实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 什么是序列化?

  程序員在編寫應用程序的時候往往需要將程序的某些數據存儲在內存中,然后將其寫入文件或是將其傳輸到網絡中的另一臺計算機上以實現通訊。這個將程序數據轉換成能被存儲并傳輸的格式的過程被稱為序列化(serialization),而它的逆過程被稱為反序列化(deserialization)。

  簡單來說,序列化就是將對象實例的狀態轉換為可保持或傳輸的格式的過程。與序列化相對的是反序列化,它根據流重構對象。這兩個過程結合起來,可以輕松地存儲和傳輸數據。

  序列化:將對象變成字節流的形式傳出去。
  反序列化:從字節流恢復成原來的對象。

2. 序列化實現

  可以通過將對象轉換成json、xml和二進制流的方式實現序列化,鑒于json和xml在不同編程語言中其組包、解包的API接口實現方法的不同,我決定采用通用的二進制流的方式實現序列化。

2.1 類圖設計

  

3. 各個組件代碼實現

3.1 元組實現

  該元組可以接納我們自定義的任意類型

  數據類型定義:

enum class Type {Invalid,Boolean,Character,Int8,Int16,Int32,Int64,Float,Double,String};

  聯合體InnerValue定義:聯合體的優點在于所有的值共享一篇存儲空間,因此不會引起額外的空間存儲消耗

union InnerValue {bool booleanValue;char characterValue;int8_t int8Value;int16_t int16Value;int32_t int32Value;int64_t int64Value;float floatValue;double doubleValue;};

  Values類實現:

#include <vector>
class Values : public std::vector<Value>
{
public:Values() = default;Values(std::initializer_list<Value> list) : std::vector<Value>(list){}Value& operator[](size_t index) {return std::vector<Value>::operator[](index);}const Value& operator[](size_t index) const {return std::vector<Value>::operator[](index);}
};

  異常類TypeMismatchException實現:

#ifdef WIN32
#define NOEXCEPT
#else
#define NOEXCEPT noexcept
#endifclass TypeMismatchException : public std::exception
{
public:TypeMismatchException(const std::string& message) :_message(message){}const char* what() const NOEXCEPT override{return _message.c_str();}private:std::string _message;
};

  元組類的使用:

Values list = {5, "hello"};for (Value value : list)
{std::cout << value << " ";
}

3.2 ByteArray類實現

  該類主要擴展字節的基本操作

class ByteArray : public std::vector<char> {
public:ByteArray() = default;ByteArray(int32_t size) :std::vector<char>(size) {}ByteArray(const char *buffer, int32_t size) :std::vector<char>(buffer, buffer + size) {}ByteArray(const std::string &str) :std::vector<char>(str.size()) {memcpy(data(), str.c_str(), str.size());}std::string ToStdString() const {std::string result(this->cbegin(), this->cend());return result;}ByteArray &Concat(const ByteArray &buffer2) {size_t oldSize = size();size_t newSize = oldSize + buffer2.size();resize(newSize);memcpy(this->data() + oldSize, buffer2.data(), buffer2.size());return *this;}ByteArray operator+(const ByteArray &buffer2) const {ByteArray buffer1(this->size() + buffer2.size());memcpy(buffer1.data(), this->data(), this->size());memcpy(buffer1.data() + this->size(), buffer2.data(), buffer2.size());return buffer1;}
};

3.3 ByteArrayReader和ByteArrayWriter類實現

  ByteArrayReader:實現二進制流到指定類型T的轉換,即將ByteArrray寫入到類型Tbuff中

  ByteArrayWriter:將T類型的Buff寫到ByteArray中

  具體代碼實現如下:

#pragma once#include "ByteArray.h"#include <stdint.h>class IODevice
{
public:enum class SeekMode{Set,Forward,Backward};
};class ByteArrayWriter : public IODevice
{
public:ByteArrayWriter(){}template <class T>int32_t Write(const T* buffer, int32_t size){int32_t nWriteSize = sizeof(T) * size;ByteArray buffer2((const char *)buffer, nWriteSize);_bytes.Concat(buffer2);return nWriteSize;}template <class T>int32_t Write(const T& value){return Write((T *)&value, 1);}int32_t Write(const ByteArray& byteArray){_bytes.Concat(byteArray);return byteArray.size();}ByteArray ToByteArray() const{return _bytes;}int32_t Tell() const{return _bytes.size();}private:ByteArray _bytes;
};class ByteArrayReader : public IODevice
{
public:ByteArrayReader(const ByteArray& byteArray):_bytes(byteArray), _pos(0){}template <class T>int32_t Read(T *buff, int32_t count){int nSizeToRead = sizeof(T) * count;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}memcpy(buff, _bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return nSizeToRead;}template <class T>T Read(){T t;int32_t nSize = Read(&t, 1);return t;}ByteArray Read(int32_t size){int nSizeToRead = size;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}ByteArray byteArray(_bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return byteArray;}int32_t Tell() const{return _pos;}void Seek(SeekMode mode, int32_t size){if(mode == SeekMode::Set){_pos = size;}else if(mode == SeekMode::Forward){_pos += size;}else if(mode == SeekMode::Backward){_pos -= size;}}
private:ByteArray _bytes;int32_t _pos;
};
View Code

3.4 各數據類型讀寫控制類實現

  在進行數據序列化和反序列化的過程中都必須根據數據類型進行指定數據類型的讀寫操作,我們用兩個map其類型和Writeable類的映射關系:

std::map<Value::Type, int32_t> CodeToTypeMap;
std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap;CodeToTypeMap.insert({ Value::Type::Int32, 5 });
CodeToTypeMap.insert({ Value::Type::String, 9 });WriterMap.insert({ 5, std::shared_ptr<IWriteble>(new Int32Writeable) });
WriterMap.insert({ 9, std::shared_ptr<IWriteble>(new StringWriteable) });

  代碼實現:

class IWriteble
{
public:virtual int32_t Write(ByteArrayWriter& Writer, const Value& value) = 0;virtual int32_t Read(ByteArrayReader& Reader, Value& value) = 0;
};class Int32Writeable : public IWriteble
{
public:Int32Writeable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{int32_t nValue = value.GetInt32Value();return Writer.Write<int32_t>(nValue);}int32_t Read(ByteArrayReader& Reader, Value& value) override{int32_t nValue = Reader.Read<int32_t>();value.SetInt32Value(nValue);return sizeof(int32_t);}
};class StringWriteable : public IWriteble
{
public:StringWriteable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{std::string stringValue = value.GetStringValue();Writer.Write(stringValue.size());Writer.Write(stringValue.c_str(), stringValue.size());return sizeof(int32_t) + stringValue.size();}int32_t Read(ByteArrayReader& Reader, Value& value) override{// 對于string類型,前4個字節為字符串的長度,后面為字符串的內容int32_t nSize = Reader.Read<int32_t>();ByteArray byteArray = Reader.Read(nSize);value.SetStringValue(byteArray.ToStdString());return sizeof(int32_t) + byteArray.size(); // 注意這個位置不應該直接寫nSize
    }
};
View Code

3.5 序列化和反序列化函數實現

class DataPachage
{
public:DataPachage(){CodeToTypeMap.insert({ Value::Type::Int32, 5 });CodeToTypeMap.insert({ Value::Type::String, 9 });WriterMap.insert({ 5, std::shared_ptr<IWriteble>(new Int32Writeable) });WriterMap.insert({ 9, std::shared_ptr<IWriteble>(new StringWriteable) });}ByteArray Serialize(const Values& values){ByteArrayWriter Writer;for (Value value : values){Value::Type type = value.GetValueType();int32_t code = CodeToTypeMap[type];std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());pInt32Writer->Write(Writer, code);std::shared_ptr<IWriteble> Writeable = WriterMap[code];Writeable->Write(Writer, value);}return Writer.ToByteArray();}Values DeSerialize(const ByteArray& byteArray){Values values;int32_t i = 0;ByteArrayReader Reader(byteArray);int32_t pos = 0;while (( pos = Reader.Tell()) < byteArray.size()){std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());Value value;pInt32Writer->Read(Reader, value);std::shared_ptr<IWriteble> Writeable = WriterMap[value.GetInt32Value()];Writeable->Read(Reader, value);values.push_back(value);}return values;}private:std::map<Value::Type, int32_t> CodeToTypeMap;std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap;
};

3.6 測試

#include "stdio.h"#include "Serialize.h"int main()
{Values list = {5, "hello"};std::cout << "序列化前Values值:" << std::endl;for (Value value : list){std::cout << value << " ";}std::cout << std::endl;DataPachage data;ByteArray bytes = data.Serialize(list);Values list1 = data.DeSerialize(bytes);std::cout << "反序列化得到Values值:" << std::endl;for (Value value : list1){std::cout << value << " ";}std::cout << std::endl;return 0;
}

  附:

#pragma once#include <vector>
#include <string>
#include <cstring>
#include <stdint.h>class ByteArray : public std::vector<char> {
public:ByteArray() = default;ByteArray(int32_t size) :std::vector<char>(size) {}ByteArray(const char *buffer, int32_t size) :std::vector<char>(buffer, buffer + size) {}ByteArray(const std::string &str) :std::vector<char>(str.size()) {memcpy(data(), str.c_str(), str.size());}std::string ToStdString() const {std::string result(this->cbegin(), this->cend());return result;}ByteArray &Concat(const ByteArray &buffer2) {size_t oldSize = size();size_t newSize = oldSize + buffer2.size();resize(newSize);memcpy(this->data() + oldSize, buffer2.data(), buffer2.size());return *this;}ByteArray operator+(const ByteArray &buffer2) const {ByteArray buffer1(this->size() + buffer2.size());memcpy(buffer1.data(), this->data(), this->size());memcpy(buffer1.data() + this->size(), buffer2.data(), buffer2.size());return buffer1;}
};
ByteArray.h
#pragma once#include "ByteArray.h"#include <stdint.h>class IODevice
{
public:enum class SeekMode{Set,Forward,Backward};
};class ByteArrayWriter : public IODevice
{
public:ByteArrayWriter(){}template <class T>int32_t Write(const T* buffer, int32_t size){int32_t nWriteSize = sizeof(T) * size;ByteArray buffer2((const char *)buffer, nWriteSize);_bytes.Concat(buffer2);return nWriteSize;}template <class T>int32_t Write(const T& value){return Write((T *)&value, 1);}int32_t Write(const ByteArray& byteArray){_bytes.Concat(byteArray);return byteArray.size();}ByteArray ToByteArray() const{return _bytes;}int32_t Tell() const{return _bytes.size();}private:ByteArray _bytes;
};class ByteArrayReader : public IODevice
{
public:ByteArrayReader(const ByteArray& byteArray):_bytes(byteArray), _pos(0){}template <class T>int32_t Read(T *buff, int32_t count){int nSizeToRead = sizeof(T) * count;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}memcpy(buff, _bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return nSizeToRead;}template <class T>T Read(){T t;int32_t nSize = Read(&t, 1);return t;}ByteArray Read(int32_t size){int nSizeToRead = size;if(_pos >= _bytes.size()){return 0;}else if (_bytes.size() - _pos < nSizeToRead){nSizeToRead = _bytes.size() - _pos;}ByteArray byteArray(_bytes.data() + _pos, nSizeToRead);_pos += nSizeToRead;return byteArray;}int32_t Tell() const{return _pos;}void Seek(SeekMode mode, int32_t size){if(mode == SeekMode::Set){_pos = size;}else if(mode == SeekMode::Forward){_pos += size;}else if(mode == SeekMode::Backward){_pos -= size;}}
private:ByteArray _bytes;int32_t _pos;
};
IODevice.h
#pragma once#include <stdint.h>
#include <exception>
#include <string>
#include <iostream>#ifdef WIN32
#define NOEXCEPT
#else
#define NOEXCEPT noexcept
#endifclass TypeMismatchException : public std::exception
{
public:TypeMismatchException(const std::string& message) :_message(message){}const char* what() const NOEXCEPT override{return _message.c_str();}private:std::string _message;
};class Value {
public:enum class Type {Invalid,Boolean,Character,Int8,Int16,Int32,Int64,Float,Double,String};union InnerValue {bool booleanValue;char characterValue;int8_t int8Value;int16_t int16Value;int32_t int32Value;int64_t int64Value;float floatValue;double doubleValue;};Value() : _type(Type::Invalid) {}Value(bool value) : _type(Type::Boolean) {_value.booleanValue = value;}Value(char value) : _type(Type::Character) {_value.characterValue = value;}Value(int8_t value) : _type(Type::Int8) {_value.int8Value = value;}Value(int16_t value) : _type(Type::Int16) {_value.int16Value = value;}Value(int32_t value) : _type(Type::Int32) {_value.int32Value = value;}Value(int64_t value) : _type(Type::Int64) {_value.int64Value = value;}Value(float value) : _type(Type::Float) {_value.floatValue = value;}Value(double value) : _type(Type::Double) {_value.doubleValue = value;}Value(const std::string& value) : _type(Type::String) {_stringValue = value;}Value(const char* value) : Value(std::string(value)) {}bool ToBoolean() const {if ( _type != Type::Boolean ) {throw TypeMismatchException("The type of value is not boolean");}}int8_t ToInt8() const {if ( _type != Type::Int8 ) {throw TypeMismatchException("The type of value is not int8");}return _value.int8Value;}int16_t ToInt16() const {if ( _type != Type::Int16 ) {throw TypeMismatchException("The type of value is not int16");}return _value.int16Value;}int32_t ToInt32() const {if ( _type != Type::Int32 ) {throw TypeMismatchException("The type of value is not int32");}return _value.int32Value;}int64_t ToInt64() const {if ( _type != Type::Int64 ) {throw TypeMismatchException("The type of value is not int64");}return _value.int64Value;}char ToCharacter() const {if ( _type != Type::Character ) {throw TypeMismatchException("The type of value is not character");}return _value.characterValue;}const std::string& ToString() const {if ( _type != Type::String ) {throw TypeMismatchException("The type of value is not string");}return _stringValue;}friend std::ostream& operator<<(std::ostream& os, const Value& value){if (value._type == Type::String){os << "value:" << value._stringValue;}else if (value._type == Type::Int32){os << "value:" << value._value.int32Value;}else if (value._type == Type::Double){os << "value:" << value._value.doubleValue;}return os;} // 以下以int32和string為例進行測試void SetInt32Value(int32_t value){_type = Type::Int32;_value.int32Value = value;}void SetStringValue(std::string value){_type = Type::String;_stringValue = value;}int32_t GetInt32Value() const {return _value.int32Value;}std::string GetStringValue() const {return _stringValue;}Type GetValueType() const {return _type;}private:Type _type;InnerValue _value;std::string _stringValue;
};#include <vector>
class Values : public std::vector<Value>
{
public:Values() = default;Values(std::initializer_list<Value> list) : std::vector<Value>(list){}Value& operator[](size_t index) {return std::vector<Value>::operator[](index);}const Value& operator[](size_t index) const {return std::vector<Value>::operator[](index);}
};
Values.h
#pragma once#include "IODevice.h"
#include "Values.h"class IWriteble
{
public:virtual int32_t Write(ByteArrayWriter& Writer, const Value& value) = 0;virtual int32_t Read(ByteArrayReader& Reader, Value& value) = 0;
};class Int32Writeable : public IWriteble
{
public:Int32Writeable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{int32_t nValue = value.GetInt32Value();return Writer.Write<int32_t>(nValue);}int32_t Read(ByteArrayReader& Reader, Value& value) override{int32_t nValue = Reader.Read<int32_t>();value.SetInt32Value(nValue);return sizeof(int32_t);}
};class StringWriteable : public IWriteble
{
public:StringWriteable(){}int32_t Write(ByteArrayWriter& Writer, const Value& value) override{std::string stringValue = value.GetStringValue();Writer.Write(stringValue.size());Writer.Write(stringValue.c_str(), stringValue.size());return sizeof(int32_t) + stringValue.size();}int32_t Read(ByteArrayReader& Reader, Value& value) override{// 對于string類型,前4個字節為字符串的長度,后面為字符串的內容int32_t nSize = Reader.Read<int32_t>();ByteArray byteArray = Reader.Read(nSize);value.SetStringValue(byteArray.ToStdString());return sizeof(int32_t) + byteArray.size(); // 注意這個位置不應該直接寫nSize
    }
};#include <map>
#include <memory>
/*std::map<Value::Type, int32_t> CodeToTypeMap =
{{Value::Type::Int32, 5},{Value::Type::String, 9}
};// 根據數據類型得到對應的IWriteble
std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap =
{{5, std::shared_ptr<IWriteble>(new Int32Writeable)},{9, std::shared_ptr<IWriteble>(new StringWriteable)}
};*///static std::map<int32_t, IWriteble*> WriterMap =
//{
//    {5, new Int32Writeable()},
//    {9, new StringWriteable()}
//};class DataPachage
{
public:DataPachage(){CodeToTypeMap.insert({ Value::Type::Int32, 5 });CodeToTypeMap.insert({ Value::Type::String, 9 });WriterMap.insert({ 5, std::shared_ptr<IWriteble>(new Int32Writeable) });WriterMap.insert({ 9, std::shared_ptr<IWriteble>(new StringWriteable) });}ByteArray Serialize(const Values& values){ByteArrayWriter Writer;for (Value value : values){Value::Type type = value.GetValueType();int32_t code = CodeToTypeMap[type];std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());pInt32Writer->Write(Writer, code);std::shared_ptr<IWriteble> Writeable = WriterMap[code];Writeable->Write(Writer, value);}return Writer.ToByteArray();}Values DeSerialize(const ByteArray& byteArray){Values values;int32_t i = 0;ByteArrayReader Reader(byteArray);int32_t pos = 0;while (( pos = Reader.Tell()) < byteArray.size()){std::shared_ptr<IWriteble> pInt32Writer = std::shared_ptr<IWriteble>(new Int32Writeable());Value value;pInt32Writer->Read(Reader, value);std::shared_ptr<IWriteble> Writeable = WriterMap[value.GetInt32Value()];Writeable->Read(Reader, value);values.push_back(value);}return values;}private:std::map<Value::Type, int32_t> CodeToTypeMap;std::map<int32_t, std::shared_ptr<IWriteble>> WriterMap;
};
Serialize.h
#include "stdio.h"#include "Serialize.h"int main()
{Values list = {5, "hello"};std::cout << "序列化前Values值:" << std::endl;for (Value value : list){std::cout << value << " ";}std::cout << std::endl;DataPachage data;ByteArray bytes = data.Serialize(list);Values list1 = data.DeSerialize(bytes);std::cout << "反序列化得到Values值:" << std::endl;for (Value value : list1){std::cout << value << " ";}std::cout << std::endl;return 0;
}
main.cpp

?

轉載于:https://www.cnblogs.com/xiaobingqianrui/p/9405457.html

總結

以上是生活随笔為你收集整理的序列化和反序列化实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。