序列化与反序列化-深入理解

序列化与反序列化-深入理解

 

序列化指的是将一个内存对象转化成一串字节数据(存储在一个字节数组中),可用于保存到本地文件或网络传输。反序列化就是将字节数据还原成内存对象。

如:

 
  1. struct student

  2. {

  3. int id;

  4. string name;

  5. };

将一个student对象转换成字节数据存储在ByteArray[20]中称为序列化代码如

 
  1. int count = 0;

  2. char ByteArray[20];

  3. student s;

  4. s.id = 12;

  5. s.name = "specialist";

  6. memcpy(ByteArray,&s.id,sizeof(s.id));

  7. count += sizeof(s.id);

  8. memcpy(ByteArray+count,s.name.c_str(),s.name.length());

  9. count += s.name.length();

把字节数据还原成student对象称为反序列化代码如

 
  1. student ss;

  2. memcpy(&ss.id,ByteArray,sizeof(ss.id));

  3. ss.name.append(ByteArray+4,count-4);

其实在上述代码中存在问题只是memcpy函数隐藏了这个细节。在vs的内存窗口中我们可以看到s.id的内存视图为0c 00 00 00(16进制),这似乎和我们想的00 00 00 0c不一样,这就是所谓的大端系统(内存中高位字节在前)和小端系统(内存中低位字节在前),而目前我们的系统大多是小端系统,而一般在网络传输中却规定使用大端传输(如果不规定当我们将0c 00 00 00这四个字节传给对方,对方就不清楚这四个字节的值?0c 00 00 00 or 00 00 00 0c),我们用memcpy函数的时候实际上就是对内存的拷贝,而前面讲了在小端系统中对于s.id这个值拷贝到bytearray中的肯定是0c 00 00 00,然后你发过去对端接收到的是0c 00 00 00值为16的6次方(也不一定如果对端也是用的C语言直接用memcpy将0c 00 00 00拷贝s.id对应的内存,s.id的值还是12,就如上述代码,但是客户端和服务端的语言不一定一样),这显然与你想发的12差太多了 ,于是我们使用位操作(语言无关)来实现序列化与反序列化,以s.id为例代码如(注意位操作针对的是数值本身而非内存不要搞混了)

 
  1. /*s.id的值为00 00 00 0c*/

  2. ByteArray[0] = s.id>>24; //移位后隐式装换(int)-->(char) 00 00 00 00 --> 00,下面类似

  3. ByteArray[1] = s.id>>26;

  4. ByteArray[2] = s.id>>8;

  5. ByteArray[3] = s.id;

这样就保证了bytearray中的值为0 00 00 0c,发到对端怎么发序列化成s.id呢?这个很容易代码如

 
  1. s.id += ByteArray[0]<<24; //移位后隐式转换(char)--(int) 00-->00 00 00 00,下面类似

  2. s.id += ByteArray[1]<<16;

  3. s.id += ByteArray[2]<<8;

  4. s.id += ByteArray[3];

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值