【问题标题】:How to convert from []byte to int in Go Programming如何在 Go 编程中将 []byte 转换为 int
【发布时间】:2012-06-26 09:55:21
【问题描述】:

我需要通过 TCP 创建一个客户端-服务器示例。在客户端,我读取了 2 个数字并将它们发送到服务器。我面临的问题是我无法从[]byte 转换为int,因为通信只接受[]byte 类型的数据。

有没有办法将[]byte 转换为int 或者我可以将int 发送到服务器?

一些示例代码将不胜感激。

谢谢。

【问题讨论】:

  • 只是为了澄清任务,您是否同时编写客户端和服务器代码?并且都是用 Go 编写的?
  • AFAIK 你必须做位移。
  • 要将数据发送到网络,它需要以字节形式。

标签: tcp client-server byte type-conversion go


【解决方案1】:

encoding/binary 中的binary.Read 提供了将字节数组转换为数据类型的机制。

请注意,网络字节顺序为BigEndian,因此在这种情况下,您需要指定binary.BigEndian

  package main

  import (
    "bytes"
    "encoding/binary"
    "fmt"
  )

  func main() {
    var myInt int
    b := []byte{0x18, 0x2d} // This could also be a stream
    buf := bytes.NewReader(b)
    err := binary.Read(buf, binary.BigEndian, &myInt) // Make sure you know if the data is LittleEndian or BigEndian
    if err != nil {
        fmt.Println("binary.Read failed:", err)
        return
    }
    fmt.Print(myInt)
  }

查看此文档可能会有所帮助:https://pkg.go.dev/encoding/binary@go1.17.1#Read

【讨论】:

    【解决方案2】:
    now := []byte{0xFF,0xFF,0xFF,0xFF}
    nowBuffer := bytes.NewReader(now)
    var  nowVar uint32
    binary.Read(nowBuffer,binary.BigEndian,&nowVar)
    fmt.Println(nowVar)
    
    4294967295
    

    【讨论】:

      【解决方案3】:

      如果 []byte 是 ASCII 字节数,则首先将 []byte 转换为字符串,然后使用 strconvAtoi 将字符串转换为 int 的方法。

      package main
      import (
          "fmt"
          "strconv"
      )
      
      func main() {
          byteNumber := []byte("14")
          byteToInt, _ := strconv.Atoi(string(byteNumber))
          fmt.Println(byteToInt)
      }
      

      去游乐场 - https://play.golang.org/p/gEzxva8-BGP

      【讨论】:

      • 将一个 int 解析为一个字符串,然后解析为一个字节数组,然后反向看起来太长了
      • 是的,一个字节到 int 会更便宜,但还没有找到方法。
      【解决方案4】:
      var bs []byte
      value, _ := strconv.ParseInt(string(bs), 10, 64)
      

      【讨论】:

      • 这大概是因为没有任何解释,它返回 int64 而不是 int,所以它被投了很多票。如果您想要 int64 (我愿意),这将是一种有效的方法吗?到字符串转换似乎是一种冗余。
      • 这个答案不符合提问者的意图。这会读取一个字节序列,将它们解释为字符,并查看这些字符是否包含数字。可以从 4 个字节返回的最大值是 '9999'。提问者在一个切片中有 4 个字节,当它们组合时,代表一个 4 字节整数,并且想知道提取其中整数的最简单方法。这可能会返回 -2^31 到 2^31-1 之间的结果。
      【解决方案5】:

      (转发this answer

      您可以使用 encoding/binary 的 ByteOrder 为 16、32、64 位类型执行此操作

      Play

      package main
      
      import "fmt"
      import "encoding/binary"
      
      func main() {
          var mySlice = []byte{244, 244, 244, 244, 244, 244, 244, 244}
          data := binary.BigEndian.Uint64(mySlice)
          fmt.Println(data)
      }
      

      【讨论】:

      • 偏移量是什么意思?例如,从 [] 字节的中间读取?只做 BigEndian.Uint64(bigSlice[10:18]) (基本上,读取切片中间的字节。还是你的意思是别的?
      • 是的,我是在问了这个愚蠢的问题后才想到的。只是无法编辑它:D 谢谢。
      • 它返回 uint16, uint32, unit64 但不返回 int。需要从uint转成int
      • 有点明显,但起初只是想将 byte[] 转换为 int:这不适用于字节数组非常小的情况。对于我的一个案例,我有一个只有 2 个元素的字节数组,而 Uint64 方法在源 _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 的这一行失败,因为显然索引超出了范围。我需要Uint16 方法。
      • @TinkalGogoi 使用 int64(value) 将值转换为 int64。
      【解决方案6】:

      对于编码/解码数字到/从字节序列,有encoding/binary 包。文档中有示例:请参阅目录中的示例部分。

      这些编码函数在io.Writer 接口上运行。 net.TCPConn 类型实现了 io.Writer,因此您可以直接写入/读取网络连接。

      如果您在连接的任一端都有 Go 程序,您可能希望使用encoding/gob 查看。有关使用 gob 的演练,请参阅文章“Gobs of data”(跳到底部查看自包含示例)。

      【讨论】:

      • 你能举个例子说明如何在 TCP 应用程序中使用 gob 吗?
      • 我添加了一个链接到一篇描述 gobs 的文章;如果您只想查看代码示例,可以跳到底部。构建编码器/解码器时,只需将*TCPConn 作为参数传递给gob.NewEncoder/gob.NewDecoder
      【解决方案7】:

      从字节数组开始,您可以使用binary package 进行转换。

      例如,如果您想读取整数:

      buf := bytes.NewBuffer(b) // b is []byte
      myfirstint, err := binary.ReadVarint(buf)
      anotherint, err := binary.ReadVarint(buf)
      

      同一包允许使用通用Read 函数读取具有所需字节顺序的无符号整数或浮点数。

      【讨论】:

      猜你喜欢
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 2010-11-08
      • 2017-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多