Go
golang
Binary

Go言語でシンプルに構造体⇔バイナリの相互変換

More than 1 year has passed since last update.

構造体をサクッとバイナリに変換したい!

そんなときはencoding/binaryパッケージを使います。

構造体→バイナリ

binary.Writeメソッドに構造体を渡すと上から順番にフィールドが並んだバイナリになります。

package main

import (
    "encoding/binary"
    "encoding/hex"
    "os"
)

type A struct {
    Int32Field int32
    ByteField byte
}

func main() {
    // 構造体つくる
    a := A{Int32Field: 0x123456, ByteField: 0xFF}

    stdoutDumper := hex.Dumper(os.Stdout)
    defer stdoutDumper.Close()

    // 構造体をバイナリにする
    binary.Write(stdoutDumper, binary.LittleEndian, &a)
}

出力

00000000  56 34 12 00 ff                                    |V4...|

https://play.golang.org/p/AJy78r6qTO

バイナリ→構造体

binary.Readメソッドにバイナリと受けの構造体を渡すと、構造体に復元できます。

package main

import (
    "encoding/binary"
    "bytes"
    "fmt"
)

type A struct {
    Int32Field int32
    ByteField byte
}

func main() {
    // 構造体つくる
    a := A{}

    // バイナリを構造体aに入れる
    bin := []byte("\x56\x34\x12\x00\xFF")
    reader := bytes.NewReader(bin)
    binary.Read(reader, binary.LittleEndian, &a)

    fmt.Printf("a: %v\n", a)
}

出力

a: {1193046 255}

https://play.golang.org/p/JP0ySnszNN

注意点

ポインタやスライスなどを含む場合

binary.Read/Write ではポインタやスライスなどの複雑な型のフィールドは扱えません。

そのような複雑なものについては、gobprotobufを検討すると良いかもしれません