【问题标题】:correct idiomatic byte buffer reading and writing正确的惯用字节缓冲区读写
【发布时间】:2014-05-20 18:51:50
【问题描述】:

我打开了一个网络/套接字。我需要离线阅读结构化协议。即我有

messagelength|type|value|type|value ...

其中messagelength为4字节,类型为1字节,值取决于类型,...

我正在尝试找出在 Go 中执行此操作的简单方法。我被 io,bufio,encoding 淹没了……我找不到合适的起点,也找不到样本。正在寻找 ReadInt32、ReadByte、....

接下来 - 我需要组合回复 -> WriteInt32, WriteString, WriteByte,....

尝试转换python去,python代码使用struct.unpack/pack

【问题讨论】:

  • 看看encoding/binary 及其提供的功能。
  • 我做到了,但没有更聪明,什么是变种,我如何将阅读器连接到网络连接,...
  • varint 并不重要。您只需要 Read() 和 Write() 函数。也看看这些例子。
  • bytes.NewBuffer 将返回一个Buffer,您可以将其用作io.Reader
  • 提示:如果两端都是用 Go 编写的 - 使用 gobs 进行二进制传输。 (如果另一端不是 Go 程序,则不适用)。

标签: go


【解决方案1】:

您可以使用包encoding/binary。您需要的唯一函数是Read() 和Write()。以下是您如何使用它们:

Read() 函数具有以下签名:

func Read(r io.Reader, order ByteOrder, data interface{}) error

此函数从r 中读取,以便将ByteOrder 读入数据。 data 必须是指向固定大小值的指针(例如 int32、字节或仅具有固定大小成员的结构)或此类值的切片。如果你传递一个指向结构体的指针,结构体字段被读取而不填充,对应于空白字段(即那些名为_)的数据被读取并丢弃(非常适合填充)。

针对您的具体问题,声明一个与您的数据流标头匹配的结构。

type Header struct {
    Length uint32
    Type   uint8
}

使用包头(假设大端):

var hdr Header
if err = Read(connection, binary.BigEndian, &hdr); err != nil {
    // deal with read error
}

切换类型字节:

switch hdr.Type {
// for each type, read into a type-specific struct
// ...
}

Write() 类似,但写入而不是读取。

【讨论】:

  • 如何将 net.Conn 连接到 io.Reader
  • @pm100 net.Conn 已经是一个 io.Reader:它的方法是 io.Reader 中方法的超集。
  • 还有一个 - 我如何从 []byte 数组中创建一个 io.Reader
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-26
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多