【问题标题】:empty slice when parsing msgpack encoded slice of msgpack encoded individual slice解析 msgpack 编码的 msgpack 编码的单个切片时的空切片
【发布时间】:2019-08-20 08:59:52
【问题描述】:

我正在尝试解码来自服务器的 gzip 响应,其中 msgpack 数组或 msgpack 数组最终被 gzip 压缩。

为了说明这一点,我的回复看起来像:

gzip(msgpack([msgpack([]), msgpack([]), msgpack([]) ....]))

这是我到目前为止所做的,但我收到 msgpack 错误

msgpack: invalid code=3f decoding array length 因此我得到的只是空切片。

这个 getBytes 函数我从这个 SO answer 中得到的

func getBytes(key interface{}) ([]byte, error) {
    var buf bytes.Buffer
    enc := gob.NewEncoder(&buf)
    err := enc.Encode(key)
    if err != nil {
        return nil, err
    }
    return buf.Bytes(), nil
}

var unZipped io.Reader
unZipped, err = gzip.NewReader(resp.Body)
var dataBytes bytes.Buffer
_, err = dataBytes.ReadFrom(unZipped)
if err != nil {
    logger.Println("error un gzipping", err)
}
var packedSlices []interface{}
bytesSlice := dataBytes.Bytes()
err = msgpack.Unmarshal(bytesSlice, &packedSlices)
for _, c := range packedSlices {
    var packedSlice []interface{}
    byts, _ := getBytes(c)
    err = msgpack.Unmarshal(byts, &packedSlice)
    logger.Println(err, packedSlice)
}

当我在 python 3.7 中做同样的事情时,它工作正常:

resp = requests.post(url, headers=headers, json=payload, stream=True)
datas = msgpack.loads(gzip.decompress(resp.raw.data))
datas = [msgpack.loads(k) for k in datas]

这里有什么我想念的吗??

【问题讨论】:

    标签: go gzip msgpack


    【解决方案1】:

    不要使用[]interface{} 类型作为解压类型,而是使用[][]byte。将根消息解组为[][]byte,然后遍历字节切片切片并解组每个子字节切片。您不需要getBytes 函数。

    这里有一些例子:

    var root [][]byte
    if err :=  msgpack.Unmarshal(bytesSlice, &root); err != nil {
        panic(err)
    }
    
    for _, childBytes := range root {
        var child []interface{}
        if err := msgpack.Unmarshal(childBytes, &child); err != nil {
            panic(err)
        }
    
        _ = child
    }
    

    【讨论】:

    • 非常感谢这就像一个魅力,还有一个问题是我的方法不起作用的任何具体原因,如果只是为了获取信息我想首先开始解组到 []interface{} 和然后将其转换为字节?
    • 其实你可以使用[]interface{},但是转换成字节应该是byts := c.([]bytes)。我认为getBytes func 不起作用,因为它将类型元数据与字节数据一起编码,您可以在此处阅读更多关于getBytes func 使用的gob 包@ 987654321@
    • 这是有道理的,是的,你说的转换也有效。
    最近更新 更多