我正在尝试在Go中读取二进制文件.
基本上我有这样的结构:
type foo struct {
A int16
B int32
C [32]byte
// and so on...
}
Run Code Online (Sandbox Code Playgroud)
我正在从文件中读取结构,如下所示:
fi, err := os.Open(fname)
// error checking, defer close, etc.
var bar foo
binary.Read(fi, binary.LittleEndian, &bar)
Run Code Online (Sandbox Code Playgroud)
现在,这应该工作,但我得到一些奇怪的结果.例如,当我读到结构时,我应该得到这个:
A: 7
B: 8105
C: // some string
Run Code Online (Sandbox Code Playgroud)
但我得到的是这个:
A: 7
B: 531169280
C: // some correct string
Run Code Online (Sandbox Code Playgroud)
这样做的原因是因为在binary.Read()读取文件时,在读取[]byte{7, 0}as int16(7)(正确的值A)之后,它会遇到切片[]byte{0, 0, 169, 31}并尝试将其转换为int32.然而,binary.Read()转换是这样的:
uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24b字节切片在哪里.
但是让我感到困惑的是在C中做同样的事情完全没问题.
如果我用C写这个:
int main()
{
int fd;
struct cool_struct {
short int A;
int32_t B;
char C[32];
// you get the picture...
} foo;
int sz = sizeof(struct cool_struct);
const char* file_name = "/path/to/my/file"
fd = open(file_name, O_RDONLY);
// more code
read(fd, &foo, sz);
// print values
}
Run Code Online (Sandbox Code Playgroud)
我得到了正确的结果.为什么我的C代码在我的Go代码不正确时才能正确显示?
假设字符串的前两个字符不是'\ 000'
你得到的是一个对齐问题,你的C编译器在int16之后增加了两个字节的填充,Go不是
最简单的修复可能只是在'A'之后添加一个虚拟(填充)int16
type foo struct
{
A int16
A_pad int16
B int32
C [32]byte
}
Run Code Online (Sandbox Code Playgroud)
或者可能是一种告诉你int32需要"4字节对齐"的方法
如果你知道一个,请编辑这个答案或发表评论
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |