-
Qyouu
你为什么要在这里中间?简单的方法是 根据需要使用请求正文b, err = io.Copy(anyWriterOrMultiwriter, r.Body)b时请求的总内容长度。err == nil还b, err = io.Copy(ioutil.Discard, r.Body)
-
绝地无双
您可以编写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}这将在您从流中读取字节数时计算字节数,关闭时它将首先消耗并计算所有剩余的未读字节数。完成流后,您可以访问长度。
-
扬帆大鱼
选项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 }