golang将字节数组转换为struct

时间:2015-07-21 01:50:09

标签: struct go casting byte

我正在寻找将字节数组转换为struct for client-server应用程序的简洁方法。 我知道大多数人都转向gob包这个解决方案但是我不控制应用程序的编码。话虽如此,我只编写了服务器应用程序而不是客户端,正在交换协议的相互合同。

我能说的最好的是以下内容。

type T struct {
    A int16
    B int8
    C []byte
}

func main() {
    // Create a struct and write it.
    t := T{A: 99, B: 10}
    buf := &bytes.Buffer{}

    buf1 := []byte{5, 100, 100}
    fmt.Println(buf1)

    buf.Write(buf1)

    //err := binary.Write(buf, binary.BigEndian, t)

    //if err != nil {
    //  panic(err)
    //}
    fmt.Println(buf)

    // Read into an empty struct.
    t = T{}
    err := binary.Read(buf, binary.BigEndian, &t)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%d %d", t.A, t.B)
}

但是,只要数字字节与结构的大小不一致,那么go就会发送一个恐慌。如果尺寸过小或尺寸过大,如何在没有恐慌的情况下将其修改为

Go playground

3 个答案:

答案 0 :(得分:2)

根据http://golang.org/pkg/encoding/binary/#Read

  

数据必须是指向固定大小值或固定大小值切片的指针。

因此,您无法在结构中使用切片[]byte 。但你可以使用固定大小的阵列 像这样: Go playground

答案 1 :(得分:0)

鉴于您使用的是私有协议。实现自己的协议是个好主意。有许多examples of how来执行此操作。

您仅受编码器实施的限制。我建议查看json.Decoder处理缓冲区而不是查看直接字节切片。它们在缓冲区上运行,对大数据流非常有用。

答案 2 :(得分:0)

我认为binpacker会对处理这种情况感到满意:

package main

import (
    "bytes"
    "fmt"

    "github.com/zhuangsirui/binpacker"
)

type T struct {
    A uint16
    B string
    C []byte
}

func main() {
    field1 := uint16(1)
    field2 := "Hello World"
    field3 := []byte("Hello World")
    buffer := new(bytes.Buffer)
    binpacker.NewPacker(buffer).
        PushUint16(field1).
        PushUint16(uint16(len(field2))).PushString(field2).
        PushUint16(uint16(len(field3))).PushBytes(field3)

    t := new(T)
    unpacker := binpacker.NewUnpacker(buffer)
    unpacker.FetchUint16(&t.A).StringWithUint16Perfix(&t.B).BytesWithUint16Perfix(&t.C)
    fmt.Println(t)
}