いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-300 (バイナリを構造体にパック・アンパック)

関連記事

Goメモ-153 (Goでのファイル I/O のやり方まとめ)(Open,Write,Append,CSV,TSV,BINARY,XML,JSON,YAML,TOML) - いろいろ備忘録日記

概要

以前に上の記事で、Goのファイル I/O についてまとめていたのですが、構造体をバイナリにアンパックするサンプルがなかったので、自分のメモ用にここに載せておこうと思います。

その他のI/Oについてのサンプルは、上の記事をご参照ください。

Goは、bytesパッケージやencodingパッケージがあるので、バイナリの扱いがとても楽ですね。

サンプル

package binaryop

import (
    "bytes"
    "encoding/binary"
    "encoding/hex"

    "github.com/devlights/gomy/output"
)

// StructReadWrite は、構造体をバイナリにパックし、それをバイナリとして書き出すサンプルです.
//
// # REFERENCES
//   - https://devlights.hatenablog.com/entry/2021/06/16/014722
//   - https://pkg.go.dev/encoding/binary@go1.20.2#Read
//   - https://pkg.go.dev/encoding/binary@go1.20.2#Write
func StructReadWrite() error {
    type St struct {
        Num  uint32
        S    [10]byte
        Num2 uint16
    }

    //
    // 以下のコードでは、エラー処理は省略している
    //

    // バイナリを生成
    var (
        buf = bytes.NewBuffer(nil)
    )

    binary.Write(buf, binary.BigEndian, uint32(0xDEADBEEF))
    binary.Write(buf, binary.BigEndian, []byte("HELLOWORLD"))
    binary.Write(buf, binary.BigEndian, uint16(0xCAFE))

    // バイナリを読み込み、構造体にパック
    var (
        bin = buf.Bytes()
        st  St
    )

    binary.Read(buf, binary.BigEndian, &st)

    // 構造体の値をバイナリとして出力
    buf.Reset()
    binary.Write(buf, binary.BigEndian, &st)

    // HEXダンプして確認
    var (
        dumpBin = func(b []byte) {
            w := hex.Dumper(output.Writer())
            defer w.Close()

            w.Write(b)
        }
        dumpSt = func(st *St) {
            w := hex.Dumper(output.Writer())
            defer w.Close()

            binary.Write(w, binary.BigEndian, st.Num)
            binary.Write(w, binary.BigEndian, st.S)
            binary.Write(w, binary.BigEndian, st.Num2)
        }
    )

    dumpBin(bin)
    output.StdoutHr()
    dumpSt(&st)
    output.StderrHr()
    dumpBin(buf.Bytes())

    return nil
}

実行すると以下のようになります。

gitpod /workspace/try-golang (master) $ task
task: [run] go run . -onetime

ENTER EXAMPLE NAME: binaryop_struct_read_write

[Name] "binaryop_struct_read_write"
00000000  de ad be ef 48 45 4c 4c  4f 57 4f 52 4c 44 ca fe  |....HELLOWORLD..|
-------------------------------------------------- 
00000000  de ad be ef 48 45 4c 4c  4f 57 4f 52 4c 44 ca fe  |....HELLOWORLD..|
-------------------------------------------------- 
00000000  de ad be ef 48 45 4c 4c  4f 57 4f 52 4c 44 ca fe  |....HELLOWORLD..|


[Elapsed] 618.32µs

参考情報

github.com

Goのおすすめ書籍

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。