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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM