3 回答

TA貢獻(xiàn)1786條經(jīng)驗(yàn) 獲得超11個(gè)贊
你為什么要在這里中間?
簡(jiǎn)單的方法是 根據(jù)需要使用請(qǐng)求正文b, err = io.Copy(anyWriterOrMultiwriter, r.Body)
b
時(shí)請(qǐng)求的總內(nèi)容長(zhǎng)度。err == nil
還b, err = io.Copy(ioutil.Discard, r.Body)

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超4個(gè)贊
您可以編寫ReadCloser一個(gè)自定義代理現(xiàn)有的并計(jì)算字節(jié)數(shù)。就像是:
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
}
這將在您從流中讀取字節(jié)數(shù)時(shí)計(jì)算字節(jié)數(shù),關(guān)閉時(shí)它將首先消耗并計(jì)算所有剩余的未讀字節(jié)數(shù)。完成流后,您可以訪問長(zhǎng)度。

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超9個(gè)贊
選項(xiàng)1
使用TeeReader,這是可擴(kuò)展的。它將閱讀器分成兩部分,其中之一使用分配的內(nèi)存計(jì)算大小。另外,在第一種情況下
?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))
選項(xiàng)2不可擴(kuò)展的方式(原始答案)
您可以只讀取正文,計(jì)算大小,然后解組為結(jié)構(gòu),這樣它就變成了:
? ? 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 關(guān)注
- 234 瀏覽
添加回答
舉報(bào)