3 回答

TA貢獻1786條經驗 獲得超11個贊
你為什么要在這里中間?
簡單的方法是 根據需要使用請求正文b, err = io.Copy(anyWriterOrMultiwriter, r.Body)
b
時請求的總內容長度。err == nil
還b, err = io.Copy(ioutil.Discard, r.Body)

TA貢獻1946條經驗 獲得超4個贊
您可以編寫ReadCloser一個自定義代理現有的并計算字節數。就像是:
type LengthReader struct {
Source io.ReadCloser
Length int
}
func (r *LengthReader) Read(b []byte) (int, error) {
n, err := r.Source.Read(b)
r.Length += n
return n, err
}
func (r *LengthReader) Close() error {
var buf [32]byte
var n int
var err error
for err == nil {
n, err = r.Source.Read(buf[:])
r.Length += n
}
closeerr := r.Source.Close()
if err != nil && err != io.EOF {
return err
}
return closeerr
}
這將在您從流中讀取字節數時計算字節數,關閉時它將首先消耗并計算所有剩余的未讀字節數。完成流后,您可以訪問長度。

TA貢獻1799條經驗 獲得超9個贊
選項1
使用TeeReader,這是可擴展的。它將閱讀器分成兩部分,其中之一使用分配的內存計算大小。另外,在第一種情況下
?maxmem := 4096
? var buf bytes.Buffer
? // comment this line out if you want to disable gathering metrics
? resp.Body = io.TeeReader(resp.Body, &buf)?
? readsize := func(r io.Reader) int {
? ? bytes := make([]byte, maxmem)
? ? var size int
? ? ? for {
? ? ? ? read, err := r.Read(bytes)
? ? ? ? if err == io.EOF {
? ? ? ? break
? ? ? }
? ? ? size += read
? ? }
? ? return size
? }
? log.Printf("Size is %d", readsize(&buf))
選項2不可擴展的方式(原始答案)
您可以只讀取正文,計算大小,然后解組為結構,這樣它就變成了:
? ? b, _ := ioutil.ReadAll(r.Body)
? ? size := len(b) // can be nil so check err in your app
? ??
? ? if err := json.Unmarshal(b, &input); err != nil {
? ? ? ? s.BadReq(w, errors.New("error reading body"))
? ? ? ? return
? ? }
- 3 回答
- 0 關注
- 237 瀏覽
添加回答
舉報