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 关注
- 176 浏览
添加回答
举报