使用 Go 中的结构更新 mmap 文件

将结构写入映射内存文件(mmap)类似,如何将结构写入 mmap 文件或使用 Go 中的结构更新 mmap 文件?

假设我的二进制文件以二进制标头开头

type MVHD struct {

    Version      byte

    Flags        [3]byte

    DateCreated  time.Time

    DateModified time.Time


    TimeUnit        uint32 // time unit per second (default = 600)

    DurationInUnits uint64 // time length (in time units)


    Raw []byte // undecoded data after decoded bits above

}

假设我想将其映射为内存文件并更新字段,这可能吗?DateModified

(我在Go中对mmap的有限阅读是它只能通过字节数组访问,但我确信有一种方法可以通过结构来访问它。我在这里找到了一个使用,但它太复杂了,我无法掌握基本思想)reflect


HUX布斯
浏览 80回答 1
1回答

呼如林

您可以使用编码/二进制来读/写固定大小的结构。此方法是可移植的,不依赖于内存布局、编译器或 CPU 体系结构。例如:// Note: using uint32 instead of time.Time for decoding.// Convert to time.Time afterwards if needed.type MVHD struct {&nbsp; &nbsp; Version&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte&nbsp; &nbsp; Flags&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [3]byte&nbsp; &nbsp; DateCreatedSecs&nbsp; uint32&nbsp; &nbsp; DateModifiedSecs uint32&nbsp; &nbsp; TimeUnit&nbsp; &nbsp; &nbsp; &nbsp; uint32 // time unit per second (default = 600)&nbsp; &nbsp; DurationInUnits uint64 // time length (in time units)}// ..or use binary.BigEndian - whichever is correct for your data.var endian = binary.LittleEndianfunc decode(rd io.Reader) (*MVHD, error) {&nbsp; &nbsp; var header MVHD&nbsp;&nbsp; &nbsp; if err := binary.Read(rd, endian, &header); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return nil, err&nbsp; &nbsp; }&nbsp; &nbsp; return &header, nil}&nbsp; &nbsp; &nbsp;&nbsp;用于将 转换为 .这将允许您使用 mmap 数据。bytes.NewReader[]byteio.Readerdecode或者,您可以手动对其进行解码:func decode2(buf []byte) (*MVHD, error) {&nbsp; &nbsp; if len(buf) < 24 {&nbsp; &nbsp; &nbsp; &nbsp; return nil, errors.New("not enough data")&nbsp; &nbsp; }&nbsp;&nbsp;&nbsp; &nbsp; return &MVHD{&nbsp; &nbsp; &nbsp; &nbsp; Version:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf[0],&nbsp; &nbsp; &nbsp; &nbsp; Flags:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [3]byte{buf[1], buf[2], buf[3]},&nbsp; &nbsp; &nbsp; &nbsp; DateCreatedSecs:&nbsp; binary.LittleEndian.Uint32(buf[4:8]),&nbsp; &nbsp; &nbsp; &nbsp; DateModifiedSecs: binary.LittleEndian.Uint32(buf[8:12]),&nbsp; &nbsp; &nbsp; &nbsp; TimeUnit:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;binary.LittleEndian.Uint32(buf[12:16]),&nbsp; &nbsp; &nbsp; &nbsp; DurationInUnits:&nbsp; binary.LittleEndian.Uint64(buf[16:24]),&nbsp; &nbsp; }, nil}同样,您可以使用二进制文件就地更新数据。字节顺序调用:Putfunc updateDateModified(buf []byte, t uint32) error {&nbsp; &nbsp; if len(buf) < 12 {&nbsp; &nbsp; &nbsp; &nbsp; return errors.New("not enough data")&nbsp; &nbsp; }&nbsp; &nbsp; binary.LittleEndian.PutUint32(buf[8:12], t)&nbsp; &nbsp; return nil}
打开App,查看更多内容
随时随地看视频慕课网APP