golang序列化以及那些坑

一、基本概念
1.什么是序列化/反序列化
把对象转换为字节序列的过程称为对象的序列化;
把字节序列恢复为对象的过程称为对象的反序列化。

2.序列化的作用
(1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中
(2)在网络上传送对象的字节序列。
在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。

3.序列化的方式
(1)json序列化

package main

import (
   "encoding/json"
   "fmt"
)
type Student struct {
   Name string
   Age uint8
   Address string
}
func main() {
   s := Student{
      "stephen",
      18,
      "henan",
   }
   data, err := json.Marshal(s)
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Printf("%s\n", string(data))
   var stu Student
   json.Unmarshal(data, &stu)
   fmt.Println(" haha", stu)
}

(2)protobuff序列化
(3)binary序列化

package main

import (
   "bytes"
   "encoding/binary"
   "fmt"
)
type Student struct {
   Name string
   Age uint8
}
func (stu *Student) Marshal() ([]byte, error) {
   // 创建一个缓冲器,缓冲的类型是byte
   buff := bytes.NewBuffer(make([]byte, 0))
   // 也可以这样创建
   // buff := new(bytes.Buffer)
   if err := binary.Write(buff, binary.BigEndian, &stu.Age); err != nil {
      return nil, err
   }
   buff.Write([]byte(stu.Name))
   return buff.Bytes(), nil
}

func (stu *Student) Unmarshal(k []byte) (err error) {
   // 创建一个缓冲器,缓冲的类型是byte
   buff := bytes.NewBuffer(k)
   if err = binary.Read(buff, binary.BigEndian, &stu.Age); err != nil {
      return
   }
   stu.Name = string(buff.Bytes())
   return
}

func main() {
   s := Student{
      "stephen",
      18,
   }
   data, err := s.Marshal()
   if err != nil {
      fmt.Println(err)
      return
   }
   var stu Student
   stu.Unmarshal(data)
   fmt.Println("haha", stu)
}

二、实际使用
遇到一个问题,编译可以,运行报错,binary.Write: invalid type *string,如果换成string,则报错binary.Write: invalid type string

定位到的出错代码:
buff := bytes.NewBuffer(make([]byte, 0, 128))
if err := binary.Write(buff, binary.BigEndian, &lk.Ino); err != nil {
panic(err)
}
if err = binary.Write(buff, binary.BigEndian, &lk.Name); err != nil {
panic(err)
}
原因是string是不确定大小的类型,binary会报错,并且不可以序列化string的指针
解决方法是序列化string内容:
buff.Write([]byte(lk.Name))
反序列化时:
lk.Name = string(buff.Bytes())

Reference:
[1] http://www.pangxieke.com/go/go-serialize.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值