[英]How to encode a struct back to a bytes buffer
我正在发出一个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)
我知道要接受我的结构,结果并gzip。
我应该使用json解码器取回值吗?
然后,我想使用该解码的json,以便最终将其gzip压缩。
另外,我在字节数组,字节缓冲区和这些读取器之间感到困惑。 这个层次结构像Java吗?
如果要将结构存储为json,最简单的方法通常是使用json.Marshal()
,如下所示:
b, err := json.Marshal(&myStruct)
在这种情况下,b将是字节片([] byte)。 以后可以使用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 json的位置,可以将gzip.NewWriter(f)
使用的参数f
替换为实现io.Writer
任何对象。 例如,您可以直接在处理程序中使用http.ResponseWriter
发送压缩后的响应:
func MyHandler(w http.ResponseWriter, r *http.Request) {
myStruct := ... // Get struct from somewhere
gz := gzip.NewWriter(w)
json.NewEncoder(gz).Encode(&myStruct)
gz.Close()
}
您的问题让我有些困惑,但这也许会有所帮助:
假设您将使用标准的http.Client
则将通过Client.Do
完成HTTP调用,该Client.Do
返回*http.Response
。
您可以从读取响应体Body
场这类型的io.ReadCloser
。 实际上,这只是一个结合了io.Reader
和io.Closer
接口的接口。 如果你知道响应是json
,你现在可以创建一个json.Decoder
使用json.NewDecoder
它接受任何io.Reader
。
重要的是要记住,所有类型io.Reader
通过在其上定义以下功能来隐式实现io.Reader
:
Read(p []byte) (n int, err error)
就像*http.Response
Body
字段是io.Reader
任何bytes.Buffer
实现io.Reader
因为它实现了Buffer.Read
函数。
相反, []byte
(字节数组)是一种标量类型,它自己无法实现任何功能。 因此[]byte
没有实现io.Reader
所以您不能仅将其传递给json.NewDecoder
。 如果您想从字节数组/切片中解码JSON,则可能应该使用json.Unmarshal
或使用bytes.Buffer
从[]byte
创建一个bytes.NewBuffer
,然后再次将其传递给json.Decoder
。
同样的概念适用于编码JSON回来,但这个时候,而不是一个io.Reader
你需要一个io.Writer
和json.Encoder
。
io.Reader
和io.Writer
是指定对象行为的接口,无论其实现如何。 bytes.Buffer
是同时实现io.Reader
和io.Writer
数据结构。 数组只是核心语言数据结构,与其他语言类似。 大多数接口的优点是,尽管有底层实现,您也可以统一使用它们。 例如,io库具有func TeeReader(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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.