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