【发布时间】:2016-03-08 19:13:06
【问题描述】:
我正在尝试找出在 Go 中读取由 Python 生成的打包二进制文件的最佳方法,如下所示:
import struct
f = open('tst.bin', 'wb')
fmt = 'iih' #please note this is packed binary: 4byte int, 4byte int, 2byte int
f.write(struct.pack(fmt,4, 185765, 1020))
f.write(struct.pack(fmt,4, 185765, 1022))
f.close()
我一直在修改我在 Github.com 和其他一些来源上看到的一些示例但我似乎无法正常工作(更新显示工作方法)。 在 Go 中做这种事情的惯用方式是什么?这是几种尝试之一
更新和工作
package main
import (
"fmt"
"os"
"encoding/binary"
"io"
)
func main() {
fp, err := os.Open("tst.bin")
if err != nil {
panic(err)
}
defer fp.Close()
lineBuf := make([]byte, 10) //4 byte int, 4 byte int, 2 byte int per line
for true {
_, err := fp.Read(lineBuf)
if err == io.EOF{
break
}
aVal := int32(binary.LittleEndian.Uint32(lineBuf[0:4])) // same as: int32(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
bVal := int32(binary.LittleEndian.Uint32(lineBuf[4:8]))
cVal := int16(binary.LittleEndian.Uint16(lineBuf[8:10])) //same as: int16(uint32(b[0]) | uint32(b[1])<<8)
fmt.Println(aVal, bVal, cVal)
}
}
【问题讨论】:
-
不是 Python 开发人员,我只能告诉你这么多......但是快速查看了
struct.pack方法的文档,你的fmt的iih意味着“ 32 位整数、32 位整数、16 位短”。你在 Go 中的结构有三个 32 位整数......不是两个 32 位整数和一个 16 位短整数。 Python 文档中还提到了一些填充/对齐,因此您需要考虑到这一点。 -
谢谢你,Simon - 这让我更仔细地了解了数据类型和大小。 Python i 是 4 个字节, h 是 2 个字节 - 我已经更新了我的代码,现在能够读取数据并获得正确的值。现在我需要弄清楚如何遍历文件。
-
您可能想查看为您的用例创建的Protocol Buffers。对我来说就像一个魅力,虽然我将它们用于 Golang 到 Java。
-
感谢马库斯的提示。我会检查一下。我想出了一个解决方案,但肯定想使用最合适的解决方案。我也想写入数据(相同的 4 字节和 2 字节整数),所以我也会查看协议缓冲区。
标签: go binaryfiles