[英]How to encode a struct back to a bytes buffer
I am making a API request and the response I get back is a bytes.Buffer. 我正在发出一个API请求,我得到的响应是一个bytes.Buffer。 I then json decode that into my struct: 然后,我将json解码为我的结构:
resp, status, err := // api call that calls http client do and returns byte buff
result := MyStruct{}
err = json.NewDecoder(response).Decode(&result)
I know want to take my struct, result, and gzip it. 我知道要接受我的结构,结果并gzip。
Should I be using a json decoder to get the value back? 我应该使用json解码器取回值吗?
I want to then take that decoded json so I can then gzip it eventually. 然后,我想使用该解码的json,以便最终将其gzip压缩。
Also, I am confused between a byte array, bytebuffer and then these readers. 另外,我在字节数组,字节缓冲区和这些读取器之间感到困惑。 Is this hierarchy like java? 这个层次结构像Java吗?
If you want to store your struct as json, the simplest way is usually to use json.Marshal()
, as in: 如果要将结构存储为json,最简单的方法通常是使用json.Marshal()
,如下所示:
b, err := json.Marshal(&myStruct)
b will in this case be a byte slice ([]byte). 在这种情况下,b将是字节片([] byte)。 This can later be gzipped using the gzip
package. 以后可以使用gzip
包将其压缩。 For instance, to gzip the bytes to a file, you could use: 例如,要将字节gzip压缩到文件中,可以使用:
f, _ := os.Create("/tmp/s.gz")
defer f.Close()
w := gzip.NewWriter(f)
w.Write(b)
w.Close()
If you want to, you can bypass creating the byte slice by using json.Encoder.Encode()
directly instead. 如果愿意,可以直接使用json.Encoder.Encode()
绕过创建字节片。
f, _ := os.Create("/tmp/s.gz")
defer f.Close()
w := gzip.NewWriter(f)
json.NewEncoder(w).Encode(&myStruct)
w.Close()
Depending on where you want to store or send the gzipped json, you can replace the parameter f
used in gzip.NewWriter(f)
to be any object that implements io.Writer
. 根据要存储或发送gzip json的位置,可以将gzip.NewWriter(f)
使用的参数f
替换为实现io.Writer
任何对象。 For instance, you can send the gzipped response using http.ResponseWriter
directly in a handler: 例如,您可以直接在处理程序中使用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()
}
I am a bit confused by your question but maybe this helps a bit: 您的问题让我有些困惑,但这也许会有所帮助:
Assuming you would use the standard http.Client
your HTTP call would be done via Client.Do
which returns an *http.Response
. 假设您将使用标准的http.Client
则将通过Client.Do
完成HTTP调用,该Client.Do
返回*http.Response
。
You can read the response body from the Body
field which is of type io.ReadCloser
. 您可以从读取响应体Body
场这类型的io.ReadCloser
。 This is actually just an interface that combines the io.Reader
and io.Closer
interface. 实际上,这只是一个结合了io.Reader
和io.Closer
接口的接口。 If you know the response is json
you can now create a json.Decoder
using json.NewDecoder
which accepts any io.Reader
. 如果你知道响应是json
,你现在可以创建一个json.Decoder
使用json.NewDecoder
它接受任何io.Reader
。
Its important to keep in mind that all types implicitly implement io.Reader
by having the following function defined on them: 重要的是要记住,所有类型io.Reader
通过在其上定义以下功能来隐式实现io.Reader
:
Read(p []byte) (n int, err error)
Just as the *http.Response
Body
field is an io.Reader
any bytes.Buffer
implements io.Reader
because it implements the Buffer.Read
function. 就像*http.Response
Body
字段是io.Reader
任何bytes.Buffer
实现io.Reader
因为它实现了Buffer.Read
函数。
In contrast a []byte
(byte array) is a scalar type that does not implement any functions on its own. 相反, []byte
(字节数组)是一种标量类型,它自己无法实现任何功能。 Therefore []byte
does not implement io.Reader
so you can not just pass this into json.NewDecoder
. 因此[]byte
没有实现io.Reader
所以您不能仅将其传递给json.NewDecoder
。 If you want to decode JSON from a byte array/slice you should probably just use json.Unmarshal
or create a bytes.Buffer
from your []byte
using bytes.NewBuffer
and then again pass that to the json.Decoder
. 如果您想从字节数组/切片中解码JSON,则可能应该使用json.Unmarshal
或使用bytes.Buffer
从[]byte
创建一个bytes.NewBuffer
,然后再次将其传递给json.Decoder
。
The same concepts apply for encoding JSON back but this time instead of an io.Reader
you need an io.Writer
and a json.Encoder
. 同样的概念适用于编码JSON回来,但这个时候,而不是一个io.Reader
你需要一个io.Writer
和json.Encoder
。
io.Reader
and io.Writer
are interfaces specifying object behaviour regardless of it implementation. io.Reader
和io.Writer
是指定对象行为的接口,无论其实现如何。 bytes.Buffer
is data structure implementing both io.Reader
and io.Writer
. bytes.Buffer
是同时实现io.Reader
和io.Writer
数据结构。 array is just core language data structure similar with others languages have. 数组只是核心语言数据结构,与其他语言类似。 Most interfaces advantage is you can operate with them uniformly despite underlying implementations. 大多数接口的优点是,尽管有底层实现,您也可以统一使用它们。 For example io library has func TeeReader(r Reader, w Writer) Reader
which returns a Reader that writes to w what it reads from r. 例如,io库具有func TeeReader(r Reader, w Writer) Reader
,它返回一个读取器,该读取器向w写入从r读取的内容。 You can use it to gzip response as you read and decode it. 您可以在读取和解码它时使用它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.