如何将结构编码回字节缓冲区

时间:2016-04-23 17:56:14

标签: json go

我正在发出API请求,我得到的响应是bytes.Buffer。 然后我将json解码为我的结构:

resp, status, err := // api call that calls http client do and returns byte buff

result := MyStruct{}
err = json.NewDecoder(response).Decode(&result)

我知道想要获取我的struct,result和gzip。

我应该使用json解码器来获取值吗?

然后我想接受解码后的json,这样我就可以最终gzip了。

另外,我在字节数组,bytebuffer和这些读者之间感到困惑。这个层次结构是否像java?

3 个答案:

答案 0 :(得分:3)

如果要将结构存储为json,最简单的方法通常是使用json.Marshal(),如:

b, err := json.Marshal(&myStruct)
在这种情况下,

b将是字节片([]字节)。稍后可以使用gzip包进行gzip压缩。例如,要将字节gzip到文件,您可以使用:

f, _ := os.Create("/tmp/s.gz")
defer f.Close()

w := gzip.NewWriter(f)
w.Write(b)
w.Close()

如果您愿意,可以直接使用json.Encoder.Encode()来绕过创建字节切片。

f, _ := os.Create("/tmp/s.gz")
defer f.Close()

w := gzip.NewWriter(f)
json.NewEncoder(w).Encode(&myStruct)
w.Close()

根据您要存储或发送gzip压缩包的位置,您可以将f中使用的参数gzip.NewWriter(f)替换为实现io.Writer的任何对象。例如,您可以直接在处理程序中使用http.ResponseWriter发送gzip压缩响应:

func MyHandler(w http.ResponseWriter, r *http.Request) {
    myStruct := ...          // Get struct from somewhere
    gz := gzip.NewWriter(w)
    json.NewEncoder(gz).Encode(&myStruct)
    gz.Close()
}

答案 1 :(得分:2)

我对你的问题感到有点困惑,但也许这有点帮助:

假设您使用标准http.Client,您的HTTP调用将通过Client.Do进行,后者返回*http.Response

您可以从类型为io.ReadCloserBody字段中读取回复正文。这实际上只是一个结合io.Readerio.Closer接口的接口。如果您知道答案为json,则现在可以使用json.NewDecoder创建json.Decoderio.Reader接受任何io.Reader

重要的是要记住所有类型隐式通过在其上定义以下函数来实现Read(p []byte) (n int, err error)

*http.Response

正如Body io.Reader字段是bytes.Buffer任何io.Reader实现[]byte一样,因为它实现了Buffer.Read函数。

相比之下,[]byte(字节数组)是一种标量类型,它本身不实现任何函数。因此io.Reader未实现json.NewDecoder,因此您无法将其传递到bytes.Buffer。如果要从字节数组/切片中解码JSON,您应该只使用json.Unmarshal或使用bytes.NewBuffer[]byte创建json.Decoder,然后再将其传递给io.Reader

相同的概念适用于编码JSON,但这次而不是io.Writer,您需要If HbInt > 65 And HbInt <= 73 Then ... End If json.Encoder

答案 2 :(得分:0)

io.Writerbytes.Buffer是指定对象行为的接口,无论其实现如何。 io.Reader是实施io.Writerfunc TeeReader(r Reader, w Writer) Reader的数据结构。数组只是与其他语言类似的核心语言数据结构。大多数接口的优点是,无论底层实现,您都可以统一使用它们。例如,io库有SomeWriter, err := os.OpenFile("some/File", os.O_WRONLY, os.ModePerm ) //gzip to file for example gzipper := gzip.NewWriter(SomeWriter) //but can be any Writer tee := io.TeeReader(response, gzipper) //and then err = json.NewDecoder(tee).Decode(&result) ,它返回一个Reader,用于写入从r读取的内容。您可以在阅读和解码时使用它来进行gzip响应。

{{1}}