猿问

如何解组包含 UTF-8 字节顺序标记 (BOM) 的 JSON 字符串?

所以,我有点已经解决了我遇到的问题。这与我是否在 C# 客户端的 StreamWriter 上使用编码有关,但我想知道如何处理这些额外的 3 个字节。


这是一个用 C# 编写的客户端和一个用 Go 编写的服务器。为什么选择 C#?稍后它将为云计算提供 Unity 应用程序。为什么去?我只是想用它。我的服务器也是 Linux 并且 Go 很容易进行 x 编译。


问题是从我的 C# 客户端发送的数据在前面附加了 3 个额外的字节,这与 Go 的Json.Unmarshal函数在数据到达服务器后直接输入它相冲突。


这是离开 C# 客户端的 JSON 格式的字符串

{"channel":0, "data": {"name":"Hasty Wombat","uuid":"e91ccc23-7e80-4189-958e-9b778dce1146","type":"Drone"}}\n


这是在通过 C# 客户端中配置了 UTF8 的流编写器之前的字节数组。

_sWriter = new StreamWriter(_tStream, System.Text.Encoding.UTF8, 8192);

长度:108


123 34 99 104 97 110 110 101 108 34 58 48 44 32 34 100 97 116 97 34 58 32 123 34 110 97 109 101 34 58 34 72 97 115 116 121 32 87 111 109 98 97 116 34 44 34 117 117 105 100 34 58 34 101 57 49 99 99 99 50 51 45 55 101 56 48 45 52 49 56 57 45 57 53 56 101 45 57 98 55 55 56 100 99 101 49 49 52 54 34 44 34 116 121 112 101 34 58 34 68 114 111 110 101 34 125 125 10

当它到达我的 Go 服务器时,它看起来像这样:

长度:111


[239 187 191 123 34 99 104 97 110 110 101 108 34 58 48 44 32 34 100 97 116 97 34 58 32 123 34 110 97 109 101 34 58 34 72 97 115 116 121 32 87 111 109 98 97 116 34 44 34 117 117 105 100 34 58 34 50 99 57 49 48 97 99 98 45 53 101 101 102 45 52 98 56 101 45 56 52 50 54 45 54 49 102 100 100 99 99 51 101 51 55 100 34 44 34 116 121 112 101 34 58 34 68 114 111 110 101 34 125 125 10]

根据我的快速研究,前面添加的这 3 个额外字节与 UTF8 的字节顺序有关。这很好,但它干扰了我将这个 JSON 字节数组解组为地图的能力。


func handleRequest (conn net.Conn) {


  for {

    data, err := bufio.NewReader(conn).ReadBytes('\n');

    if err != nil {

      fmt.Println("Client disconnect")

      conn.Close()

      return

    }


    var mappedData map[string]interface{}

    err = json.Unmarshal(data, &mappedData)

    if err != nil {

      fmt.Println("err:", err)

      continue

    }


  // ...

  }

}


err: invalid character 'ï' looking for beginning of value

Go 中的Json.Unmarshal函数不喜欢那个字节数组。起初我的解决方法是只切掉前 3 个字节。但是,当我开始添加 TCP 输出未添加这 3 个字节的 Go 客户端时,这会导致问题。


现在我想知道 Go 是否有正确解码 UTF8 字节数组的东西,或者正确检测那些额外字节(或任何额外的编码字节)的东西,并给我Json.Unmarshal函数想要的原始 JSON。我正在尝试将我的 Stream Writer 设置为多功能,但我不确定我是否需要编码 UTF8 的东西或有什么优势。


泛舟湖上清波郎朗
浏览 125回答 1
1回答

慕的地6264312

UTF-8 具有明确定义的字节顺序。没有 big-endian UTF-8 与 little-endian UTF-8 这样的东西;只有UTF-8。这意味着UTF-8 中的字节顺序标记或 BOM 是没有意义的。一些软件认为这很有意义:它将数据文件标记为以 UTF-8 存储(与 UTF-16-LE 或 UTF-16-BE 相比,每个都以两个字节 0xFF 和 0xFE 开头,但顺序不同,如果该 UTF-16-xx 文件有 BOM)。只要您同意此类软件是错误的,就不要使用它,或者以不符合初始 BOM 的方式使用它。正如Jim B 所指出的,生成 JSON 文本的系统不得在其输出的前面嵌入 UTF-8 化的 BOM(输出为三个字节 0xEF、0xBB、0xBF)。但是,它可以在流的开头接受和忽略 BOM。要在 Go 中执行此操作,请检查传入的流数据并删除初始 BOM(如果存在),将其余数据作为 JSON 字节传递。但是你可能最好让你的 C# 代码生成允许的输出,而不是幻想你的 Go 代码来允许禁止的输入。
随时随地看视频慕课网APP

相关分类

Go
我要回答