【问题标题】:Removing NUL characters from bytes从字节中删除 NUL 字符
【发布时间】:2013-03-04 02:25:51
【问题描述】:

为了自学 Go,我正在构建一个简单的服务器,它接受一些输入、进行一些处理并将输出发送回客户端(包括原始输入)。

输入的长度可以从大约 5 到 13 个字符 + 结束线以及客户​​端发送的任何其他内容不等。

输入被读入字节数组,然后转换为字符串进行一些处理。另一个字符串被附加到这个字符串,整个内容被转换回字节数组以发送回客户端。

问题是输入填充了一堆 NUL 字符,我不知道如何摆脱它们。

所以我可以遍历数组,当我遇到一个 nul 字符时,记下长度 (n),创建一个该长度的新字节数组,并将前 n 个字符复制到新字节数组并使用它.这是最好的方法,还是有什么方法可以让我更轻松?

一些精简的代码:

data := make([]byte, 16)
c.Read(data)

s := strings.Replace(string(data[:]), "an", "", -1)
s = strings.Replace(s, "\r", "", -1)
s += "some other string"
response := []byte(s)
c.Write(response)
c.close()

另外,如果我在这里做任何其他明显愚蠢的事情,我会很高兴知道。

【问题讨论】:

    标签: go


    【解决方案1】:

    在包“bytes”中,func Trim(s []byte, cutset string) []byte 是你的朋友:

    Trim 通过切掉切割集中包含的所有前导和尾随 UTF-8 编码的 Unicode 代码点来返回 s 的子切片。

    // Remove any NULL characters from 'b'
    b = bytes.Trim(b, "\x00")
    

    【讨论】:

    • 谢谢。我想我已经尝试过了,但似乎无法使用 \0,我想这是我的问题。
    • @Knyght:是的,因为\0 是一个非法的转义序列(检查specs)。必须使用\000:play.golang.org/p/KP8WLyfUB-
    • @zzzz - 我有一个 Dim Buffer() As Byte。所以对于这个 Buffer = bytes.Trim(Buffer,"\x00") bytes 在 VB.net 中显示错误
    • @Piyush 这个问题是关于 golang 的。
    • 遇到了与\u0000(又名NULL)类似的问题,效果很好。
    【解决方案2】:

    您的方法听起来基本正确。一些备注:

    1. 当你找到data中第一个nul字节的索引后,就不需要复制了,直接截断切片:data[:idx]

    2. bytes.Index 应该能够为您找到该索引。

    3. 还有bytes.Replace所以不用转成字符串了。

    【讨论】:

    • 我在使用带字节的控制字符时遇到问题。除非我在那里做错了什么,否则请替换。
    【解决方案3】:

    io.Reader 文档说:

    Read 最多将 len(p) 个字节读入 p。它返回读取的字节数 (0

    如果应用程序中对 Read 的调用未读取 16 个字节,则 data 将有尾随零字节。使用读取的字节数从缓冲区中修剪零字节。

    data := make([]byte, 16)
    n, err := c.Read(data)
    if err != nil {
       // handle error
    }
    data = data[:n]
    

    还有一个问题。无法保证 Read 会吞下对等方发送的所有“消息”。应用程序可能需要多次调用 Read 才能获得完整的消息。

    您在问题中提到了结尾。如果来自客户端的消息以换行符终止,则使用bufio.Scanner 从连接中读取行:

     s := bufio.NewScanner(c)
     if s.Scan() {
         data = s.Bytes() // data is next line, not including end lines, etc.
     }
     if s.Err() != nil {
         // handle error
     } 
    

    【讨论】:

      【解决方案4】:

      你可以利用Read的返回值:

      package main
      import "strings"
      
      func main() {
         r, b := strings.NewReader("north east south west"), make([]byte, 16)
         n, e := r.Read(b)
         if e != nil {
            panic(e)
         }
         b = b[:n]
         println(string(b) == "north east south")
      }
      

      https://golang.org/pkg/io#Reader

      【讨论】:

        猜你喜欢
        • 2013-10-20
        • 2018-07-27
        • 1970-01-01
        • 2016-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-13
        相关资源
        最近更新 更多