zoukankan      html  css  js  c++  java
  • golang 对struct进行Serialize的方法,即将存取二进制文件到struct的方法

    方法一:

    serialize 的标准方法:

    使用gobbase64 或 base58。

    方法二:

    下面是自己实现的 serialize 方法,不推荐自己实现,应该用标准方法。

    代码如下:

    package main
    
    import (
        "bytes"
        "encoding/binary"
        "fmt"
        "log"
        "os"
    )
    
    //this type represnts a record with three fields
    type payload struct {
        Three int32
    }
    
    func main() {
        writeFile()
        readFile()
    }
    
    func readFile() {
        file, err := os.Open("test.bin")
        defer file.Close()
        if err != nil {
            log.Fatal(err)
        }
    
        m := payload{}
        for i := 0; i < 10; i++ {
            data := readNextBytes(file, 4)
            buffer := bytes.NewBuffer(data)
            err = binary.Read(buffer, binary.BigEndian, &m)
            if err != nil {
                log.Fatal("binary.Read failed", err)
            }
    
            fmt.Println("m is: ", m)
        }
    }
    
    func readNextBytes(file *os.File, number int) []byte {
        bytes := make([]byte, number)
    
        _, err := file.Read(bytes)
        if err != nil {
            log.Fatal(err)
        }
    
        return bytes
    }
    
    func writeFile() {
        file, err := os.Create("test.bin")
        defer file.Close()
        if err != nil {
            log.Fatal(err)
        }
    
        for i := 0; i < 10; i++ {
            s := &payload{
                int32(i),
            }
            fmt.Println(s)
            var bin_buf bytes.Buffer
            binary.Write(&bin_buf, binary.BigEndian, s)
    
            b := bin_buf.Bytes()
            l := len(b)
            fmt.Println("write len: ", l)
    
            writeNextBytes(file, b)
        }
    }
    
    func writeNextBytes(file *os.File, bytes []byte) {
        _, err := file.Write(bytes)
    
        if err != nil {
            log.Fatal(err)
        }
    }

    除了将数据放进结构体之外,你还可以直接将数据放进结构体对象的某个成员里:

    binary.Read(buffer, binary.BigEndian, &m.Two)

    不过要保证buffer与成员的内存长度一样。

    # 注意,这里必须注意payload结构里的任何field成员都不能是 int,必须制定成员的byte长度,也即必须使用 int32, int64, float32等等,不能使用 int, float。因为不指定长度若将它存到磁盘并读取回来时会产生歧义,不知道读写多少个byte的。

    另外,如果出现这种错误: reflect: reflect.Value.SetUint using value obtained using unexported field, 是因为payload结构体内的Field的名称小写引起的,改成首字母大写即可。

    如果你向确认结构体是否被正确的赋值了,可以:

    bs := make([]byte, 4)
    binary.LittleEndian.PutUint32(bs, 31415926)
    fmt.Println(bs)
  • 相关阅读:
    UBI系统原理分析【转】
    udhcpc命令【转】
    Device Tree(三):代码分析【转】
    Linux 中断详解 【转】
    ROS探索总结(三)——ROS新手教程【转】
    机器人操作系统(ROS)教程4:ROS的框架【转】
    你知道市面上机器人都用哪些操作系统吗【转】
    dump_stack调用过程【原创】
    #if、#ifdef、#if defined之间的区别【转】
    浅析firmware完整生存和使用流程 【转】
  • 原文地址:https://www.cnblogs.com/welhzh/p/9188175.html
Copyright © 2011-2022 走看看