binary.Read()在结构

时间:2018-10-09 18:38:43

标签: parsing go binary

我正在尝试制作一个MOBI文件解析器,并且试图通过binary.Read()将一些二进制文件解析为结构时遇到了一个问题。

我认为这是一个对齐问题,但是我迷茫的为什么没有得到期望值。我已经通过libmobi运行.mobi文件以测试我的代码的输出,并检查了.mobi的二进制文件,以验证我没有发疯并且libmobi代码没有做任何奇怪的事情(这是不是)。

这是一个简化的示例:

package main

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

type Header struct {
    Type        [4]byte
    Creator     [4]byte
    Uid         uint32
    Next        uint32
    RecordCount uint16
}

func main() {
    testBytes := []byte{66, 79, 79, 75, 77, 79, 66, 73, 0, 0, 1, 17, 0, 0, 0, 0, 0, 136}

    h := Header{}
    buf := bytes.NewBuffer(testBytes)
    binary.Read(buf, binary.LittleEndian, &h)

    fmt.Printf("%s\n", h.Type)    // BOOK, as expected
    fmt.Printf("%s\n", h.Creator) // MOBI, as expected
    fmt.Printf("%d\n", h.Next)    // 0, as expected

    fmt.Printf("%d\n", h.Uid)
    // expecting Uid to be 273, but it's 285278208...
    fmt.Printf("%d\n", h.RecordCount)
    // expecting RecordCount to be 136, but it's 34816...
}

任何帮助将不胜感激!

编辑:这是在xxd上进行book.mobi的十六进制字节:

424f 4f4b 4d4f 4249 0000 0111 0000 0000 0088

1 个答案:

答案 0 :(得分:1)

是的,BigEndian的效果更好

package main

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

type Header struct {
    Type        [4]byte
    Creator     [4]byte
    Uid         uint32
    Next        uint32
    RecordCount uint16
}

func main() {
    testBytes := []byte{66, 79, 79, 75, 77, 79, 66, 73, 0, 0, 1, 17, 0, 0, 0, 0, 0, 136}

    h := Header{}
    buf := bytes.NewBuffer(testBytes)
    binary.Read(buf, binary.BigEndian, &h)

    fmt.Printf("%s\n", h.Type)    // BOOK, as expected
    fmt.Printf("%s\n", h.Creator) // MOBI, as expected
    fmt.Printf("%d\n", h.Next)    // 0, as expected

    fmt.Printf("%d\n", h.Uid)
    // expecting Uid to be 273, but it's 285278208...
    fmt.Printf("%d\n", h.RecordCount)
    // expecting RecordCount to be 136, but it's 34816...
}