如何解压缩gzip格式的[]字节内容,以便在解组时出错

时间:2013-10-07 15:17:31

标签: utf-8 go

我正在向API发出请求,我从响应中获得[]byteioutil.ReadAll(resp.Body))。我正在尝试解组这些内容,但似乎没有编码为utf-8格式,因为unmarshal会返回错误。我正在尝试这样做:

package main

import (
    "encoding/json"
    "fmt"

    "some/api"
)

func main() {
    content := api.SomeAPI.SomeRequest() // []byte variable
    var data interface{}
    err := json.Unmarshal(content, &data)
    if err != nil {
        panic(err.Error())
    }
    fmt.Println("Data from response", data)
}

我得到invalid character '\x1f' looking for beginning of value的错误。对于记录,响应包含在标题Content-Type:[application/json; charset=utf-8]中。

如何在解组时解码content以避免这些无效字符?

修改

这是contentplay.golang.org/p/oJ5mqERAmj

的hexdump

1 个答案:

答案 0 :(得分:10)

根据您的十六进制转储判断,您正在接收gzip编码数据,因此您需要先使用compress/gzip对其进行解码。

尝试这样的事情

package main

import (
    "bytes"
    "compress/gzip"
    "encoding/json"
    "fmt"
    "io"
    "some/api"
)

func main() {
    content := api.SomeAPI.SomeRequest() // []byte variable

    // decompress the content into an io.Reader
    buf := bytes.NewBuffer(content)
    reader, err := gzip.NewReader(buf)
    if err != nil {
        panic(err)
    }

    // Use the stream interface to decode json from the io.Reader
    var data interface{}
    dec := json.NewDecoder(reader)
    err = dec.Decode(&data)
    if err != nil && err != io.EOF {
        panic(err)
    }
    fmt.Println("Data from response", data)
}

<强>上

字符\x1f是ASCII和UTF-8中的单位分隔符。它绝不是UTF-8编码的一部分,但可用于标记不同的文本位。据我所知,带有\x1f的字符串可以是有效的UTF-8但不是有效的json。

我认为你需要仔细阅读API规范,找出他们使用\x1f标记的内容,但与此同时你可以尝试删除它们,看看会发生什么,例如

import (
    "bytes"
    "fmt"
)

func main() {
    b := []byte("hello\x1fGoodbye")
    fmt.Printf("b was %q\n", b)
    b = bytes.Replace(b, []byte{0x1f}, []byte{' '}, -1)
    fmt.Printf("b is now %q\n", b)
}

打印

b was "hello\x1fGoodbye"
b is now "hello Goodbye"

Playground link