簡體   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