file - 在 Go 中使用 struct 更新 mmap 文件
问题描述
类似于将结构写入映射内存文件(mmap),如何在 Go 中将结构写入 mmap 文件或使用 struct 更新 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 的有限阅读是它只能通过字节数组访问,但我确信有一种方法可以通过 struct 访问它。我在这里找到了一个使用reflect
但它对我来说太复杂了,无法掌握基本知识主意)
解决方案
您可以使用encoding/binary
读取/写入固定大小的结构。这种方法是可移植的,不依赖于内存布局、编译器或 CPU 架构。例如:
// Note: using uint32 instead of time.Time for decoding.
// Convert to time.Time afterwards if needed.
type MVHD struct {
Version byte
Flags [3]byte
DateCreatedSecs uint32
DateModifiedSecs uint32
TimeUnit uint32 // time unit per second (default = 600)
DurationInUnits uint64 // time length (in time units)
}
// ..or use binary.BigEndian - whichever is correct for your data.
var endian = binary.LittleEndian
func decode(rd io.Reader) (*MVHD, error) {
var header MVHD
if err := binary.Read(rd, endian, &header); err != nil {
return nil, err
}
return &header, nil
}
用于bytes.NewReader
将 a[]byte
转换为io.Reader
. 这将允许您使用decode
mmap 数据。
或者,您可以手动对其进行解码:
func decode2(buf []byte) (*MVHD, error) {
if len(buf) < 24 {
return nil, errors.New("not enough data")
}
return &MVHD{
Version: buf[0],
Flags: [3]byte{buf[1], buf[2], buf[3]},
DateCreatedSecs: binary.LittleEndian.Uint32(buf[4:8]),
DateModifiedSecs: binary.LittleEndian.Uint32(buf[8:12]),
TimeUnit: binary.LittleEndian.Uint32(buf[12:16]),
DurationInUnits: binary.LittleEndian.Uint64(buf[16:24]),
}, nil
}
同样,您可以通过调用更新数据:binary.ByteOrder
Put
func updateDateModified(buf []byte, t uint32) error {
if len(buf) < 12 {
return errors.New("not enough data")
}
binary.LittleEndian.PutUint32(buf[8:12], t)
return nil
}
推荐阅读
- math - 如何在不解密的情况下将非对称加密中的值相乘
- .net-5 - .NET 5 Web API Identity.User.Name 在同时使用 Windows 身份验证和匿名身份验证时为空
- python - 如何在python中将回溯消息打印到新行
- css - 我需要帮助使几个元素对我网站上的视口更具响应性。(CSS)
- postgresql - 在修饰符反对 JS 中使用关系映射
- amazon-web-services - AWS SAM - 在另一个 SAM 模板中部署新的 Lambda 函数时,有什么方法可以附加现有的 API 网关
- python - 部署后Django heroku编程错误数据库不存在
- c# - 如何在 C# 中创建运行命令行实用程序的绝对路径
- google-cloud-platform - 如何将谷歌云虚拟机链接到子域
- python - 如何在python中获得相当于top的TIME+列