Json 如何将结构编码回字节缓冲区
我发出一个API请求,得到的响应是bytes.Buffer。 然后我将其解码到我的结构中:Json 如何将结构编码回字节缓冲区,json,go,Json,Go,我发出一个API请求,得到的响应是bytes.Buffer。 然后我将其解码到我的结构中: resp, status, err := // api call that calls http client do and returns byte buff result := MyStruct{} err = json.NewDecoder(response).Decode(&result) 我知道我想获取我的结构、结果和gzip 我应该使用json解码器获取值吗? 然后,我想获取解码后
resp, status, err := // api call that calls http client do and returns byte buff
result := MyStruct{}
err = json.NewDecoder(response).Decode(&result)
我知道我想获取我的结构、结果和gzip
我应该使用json解码器获取值吗?
然后,我想获取解码后的json,这样我最终就可以gzip它了
此外,我还混淆了字节数组、bytebuffer和这些读取器。这个层次结构像java吗?我被你的问题弄糊涂了,但也许这有点帮助: 假设您使用的是标准HTTP,那么您的HTTP调用将通过
Client.Do
完成,它返回一个
您可以从类型为的body
字段中读取响应正文。这实际上只是一个结合了and接口的接口。如果您知道响应是json
,现在可以创建一个json.Decoder
,使用它接受任何io.Reader
重要的是要记住,所有类型都通过在其上定义以下函数来隐式实现io.Reader
:
Read(p []byte) (n int, err error)
正如*http.Response
Body
字段是一个io.Reader
任何字节。Buffer
实现io.Reader
,因为它实现了该功能
相比之下,[]字节(字节数组)是一种标量类型,它本身不实现任何功能。因此,[]字节
不实现io.Reader
,因此不能将其传递到json.NewDecoder
。如果您想从字节数组/切片解码JSON,您可能只需要使用或从[]字节创建字节.Buffer
,然后再次将其传递给JSON.Decoder
同样的概念也适用于将JSON编码回来,但这次不是使用io.Reader
,而是使用io.Writer
和io.Reader
和io.Writer
接口来指定对象行为,而不管其实现如何bytes.Buffer
是实现io.Reader
和io.Writer
的数据结构。数组正是与其他语言相似的核心语言数据结构。大多数接口的优点是,不管底层实现如何,您都可以统一使用它们。例如,io库有func-teereder(r-Reader,w-Writer)Reader
,它返回一个读卡器,该读卡器向w写入它从r读取的内容。您可以在读取和解码时使用它来生成gzip响应
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)
如果要将结构存储为json,最简单的方法通常是使用,如:
在这种情况下,b将是一个字节片([]字节)。这可以在以后使用gzip
包进行gzip压缩。例如,要将字节gzip到文件中,可以使用:
f, _ := os.Create("/tmp/s.gz")
defer f.Close()
w := gzip.NewWriter(f)
w.Write(b)
w.Close()
如果愿意,可以直接使用来绕过创建字节片
f, _ := os.Create("/tmp/s.gz")
defer f.Close()
w := gzip.NewWriter(f)
json.NewEncoder(w).Encode(&myStruct)
w.Close()
根据要存储或发送gzip json的位置,可以将gzip.NewWriter(f)
中使用的参数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()
}
如果您已经将所有数据设置为[]字节
,那么我更喜欢使用json.marshall
。如果您使用流式数据和/或您只有一个io.Reader
,那么json.Decoder
就是一个不错的选择。
func MyHandler(w http.ResponseWriter, r *http.Request) {
myStruct := ... // Get struct from somewhere
gz := gzip.NewWriter(w)
json.NewEncoder(gz).Encode(&myStruct)
gz.Close()
}