GoLang:在结构体中使用可变长度数组以便与二进制读取一起使用

huangapple go评论87阅读模式
英文:

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 //&quot;payload&quot; 

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
}

huangapple
  • 本文由 发表于 2015年1月19日 01:59:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/28012952.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定