繁体   English   中英

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

[英]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.Readerio.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.Writerjson.Encoder

io.Readerio.Writer是指定对象行为的接口,无论其实现如何。 bytes.Buffer是同时实现io.Readerio.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM