英文:
GoLang: Variable length array in struct for use with binary read
问题
我正在尝试在Go中重新实现几年前用C编写的程序。
该程序应该读取一个类似"记录"的结构化二进制文件,并对记录执行某些操作(对记录本身的操作对于这个问题不重要)。
这样的数据文件由许多记录组成,每个记录具有以下定义:
REC_LEN U2 // 头部之后的记录长度
REC_TYPE U1 // 类型
REC_SUB U1 // 子类型
REC_LEN x U1 // "有效载荷"
我的问题是如何在Go的结构体中指定可变长度的字节数组?
我的计划是使用binary.Read来读取记录。
以下是我在Go中尝试过的代码:
type Record struct {
rec_len uint16
rec_type uint8
rec_sub uint8
data [rec_len]byte
}
不幸的是,似乎我不能在结构体内部引用结构体的字段,因为我得到了以下错误:
xxxx.go:15: undefined: rec_len
xxxx.go:15: invalid array bound rec_len
我希望能得到指导,指引我正确的方向。
谢谢!
KR
英文:
<br>
I'm trying to reimplement a program it did in C a few years ago in Go<br>
The program should read a "record"-like structured binary file and do something with the record (what is done with the records itself is not relevant for this question)<br><br>
Such a datafile consists of many records where each record has the following definition:<br>
REC_LEN U2 // length of record after header
REC_TYPE U1 //a type
REC_SUB U1 //a subtype
REC_LEN x U1 //"payload"
My problem now is how to specify that variable length byte[] in a struct in Go?<br>
My plan was to use binary.Read to read the records<br>
Here's what I've tried so far in Go:
type Record struct {
rec_len uint16
rec_type uint8
rec_sub uint8
data [rec_len]byte
}
Unfortunatelly it seems I can't reference a field of a struct within the same struct as I get the following error:<br>
xxxx.go:15: undefined: rec_len
xxxx.go:15: invalid array bound rec_len
I'd appreciate any ideas pointing me in the right direction<br>
Thanks<br>
KR
答案1
得分: 3
你可以按照以下方式读取记录:
var rec Record
// 读取固定大小的头部信息。
var buf [4]byte
_, err := io.ReadFull(r, buf[:])
if err != nil {
// 处理错误
}
rec.rec_len = binary.BigEndian.Uint16(buf[0:2])
rec.rec_type = buf[2]
rec.rec_sub = buf[3]
// 创建变量部分并读取它。
rec.data = make([]byte, rec.rec_len)
_, err = io.ReadFull(r, rec.data)
if err != nil {
// 处理错误
}
英文:
You can read the record as follows:
var rec Record
// Slurp up the fixed sized header.
var buf [4]byte
_, err := io.ReadFull(r, buf[:])
if err != nil {
// handle error
}
rec.rec_len = binary.BigEndian.Uint16(buf[0:2])
rec.rec_type = buf[2]
rec.rec_sub = buf[3]
// Create the variable part and read it.
rec.data = make([]byte, rec.rec_len)
_, err = io.ReadFull(r, rec.data)
if err != nil {
// handle error
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论