douxianwu2221
douxianwu2221
2015-01-18 17:59
浏览 383
已采纳

GoLang:结构中的可变长度数组,用于二进制读取


I'm trying to reimplement a program it did in C a few years ago in Go
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)

Such a datafile consists of many records where each record has the following definition:

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?
My plan was to use binary.Read to read the records
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:

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
Thanks
KR

图片转代码服务由CSDN问答提供 功能建议


我正在尝试重新实现几年前在Go中用C语言编写的程序
程序应读取类似于“记录”的结构化二进制文件,并对该记录进行某些操作(对记录本身所做的操作与此问题无关)

此类数据文件由许多记录组成 其中每个记录具有以下定义:

  REC_LEN U2 //标头后的记录长度
REC_TYPE U1 //类型
REC_SUB U1 //子类型
REC_LEN  x U1 //“有效载荷” 
   
 
 

我现在的问题是如何在Go中的结构中指定可变长度的byte []?
我的计划是 使用二进制文件。读取以读取记录
这是我到目前为止在Go中尝试过的操作:

  type记录结构{
 rec_len uint16 
 rec_type uint8  
 rec_sub uint8 
数据[rec_len] byte 
} 
   
 
 

不幸的是,看来我无法在与我相同的struct中引用该struct的字段 得到以下错误 :

  xxxx.go:15:未定义:rec_len 
xxxx.go:15:无效的数组绑定rec_len 
   
  
 

如果有任何指向正确方向的想法,我将不胜感激
感谢
KR

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongtiaobeng7901
    dongtiaobeng7901 2015-01-18 19:20
    已采纳

    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
    }
    
    点赞 评论

相关推荐