Go: Tracking POST request progress

半世苍凉 提交于 2019-11-30 15:29:30

You can create your own io.Reader to wrap the actual reader and then you can output the progress each time Read is called.

Something along the lines of:

type ProgressReader struct {
    io.Reader
    Reporter func(r int64)
}

func (pr *ProgressReader) Read(p []byte) (n int, err error) {
    n, err = pr.Reader.Read(p)
    pr.Reporter(int64(n))
    return
}

func main() {
    file, _ := os.Open("/tmp/blah.go")
    total := int64(0)
    pr := &ProgressReader{file, func(r int64) {
        total += r
        if r > 0 {
            fmt.Println("progress", r)
        } else {
            fmt.Println("done", r)
        }
    }}
    io.Copy(ioutil.Discard, pr)
}

Wrap the reader passed as the request body with something that reports progress. For example,

type progressReporter struct {
     r io.Reader
     max int
     sent int
}

func (pr *progressReader) Read(p []byte) (int, error) {
     n, err := pr.r.Read(p)
     pr.sent += n
     if err == io.EOF {
         pr.atEOF = true
     }
     pr.report()
     return n, err
}

func (pr *progressReporter) report() {
   fmt.Printf("sent %d of %d bytes\n", pr.sent, pr.max)
   if pr.atEOF {
     fmt.Println("DONE")
   }
}

If previously you called

client.Post(u, contentType, r)

then change the code to

client.Post(u, contentType, &progressReader{r:r, max:max})

where max is the number of bytes you expect to send. Modify the progressReporter.report() method and add fields to progressReporter to meet your specific needs.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!