【问题标题】:Why is my upload progress bar finishing before the transfer completes?为什么我的上传进度条在传输完成之前完成?
【发布时间】:2017-01-24 06:11:57
【问题描述】:

我正在向 API 发送 POST 请求,并使用第三方库 (https://github.com/cheggaaa/pb),但我的上传进度条将在文件传输实际完成之前完成。

package main

import(
    pb "gopkg.in/cheggaaa/pb.v1"
    "net/http"
)

func main() {
    file, e := os.Open(path)
    if e != nil {
        log.Fatal()
    }
    defer file.Close()

    bar := pb.New(int(fi.Size()))
    bar.Start()


    req, err := http.NewRequest("POST", url, body)

    resp, err := client.Do(req)

    bar.Finish()

    return
}

开始于

12.64 MB / 12.64 MB [======================] 100.00% 12.59 MB/s 0s

完成后转到:

12.64 MB / 12.64 MB [======================] 100.00% 626.67 KB/s 20s

这是因为 HTTP Req 处理程序正在将文件读入内存并增加进度条吗?我错过了什么?

我查看了这篇文章 (Go: Tracking POST request progress),但我看不出它与我正在使用的库有何不同。我以前尝试过使用io.Copy 到一个缓冲区,进度条阅读器从中读取,但是一旦发送请求,它就会做同样的事情。

【问题讨论】:

标签: http post go progress-bar httprequest


【解决方案1】:

正如我在评论中所写,您的问题并未包含所有必需的信息,但这里是将文件作为multipart-form 发布到带有进度条的远程服务器的示例应用程序:

package main

import (
    "github.com/cheggaaa/pb"
    "os"
    "time"
    "bytes"
    "mime/multipart"
    "io"
    "io/ioutil"
    "net/http"
)

func main() {
    body := &bytes.Buffer{}
    bodyWriter := multipart.NewWriter(body)

    fw, _ := bodyWriter.CreateFormFile("file", "filename.jpg")
    fh, _ := os.Open("filename.jpg")

    io.Copy(fw, fh)
    bodyWriter.Close()

    bar := pb.New(body.Len()).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10)
    bar.ShowSpeed = true
    bar.Start()

    reader := bar.NewProxyReader(body)

    resp, _ := http.Post("http://domain.com", bodyWriter.FormDataContentType(), reader)
    defer resp.Body.Close()

    response, _ := ioutil.ReadAll(resp.Body)
    print(string(response))
}

【讨论】:

  • 谢谢!不过,我不想/不能使用多部分格式上传。不过我确实解决了。
【解决方案2】:

知道了,原来是另一个包导致 HTTP 请求出现问题。下面的代码完美运行。

package main

import(
    pb "gopkg.in/cheggaaa/pb.v1"
    "fmt"
    "os"
    "log"
    "io/ioutil"
    "net/http"
)

func main() {
    path := "/Users/me/testfile.txt"
    file, e := os.Open(path)
    if e != nil {
        log.Fatal("File Error")
    }
    defer file.Close()
    fi, e := file.Stat()
    if e != nil {
      log.Fatal("File Stat Error")
    }

    bar := pb.New(int(fi.Size()))
    bar.Start()

    client := &http.Client{}
    req, e := http.NewRequest("POST", "http://posttestserver.com/post.php", bar.NewProxyReader(file))
    if e != nil {
      log.Fatal("Request Error")
    }
    resp, e := client.Do(req)
    if e != nil {
      log.Fatal("Response Error")
    }
    bar.Finish()
    respBody, e := ioutil.ReadAll(resp.Body)
    fmt.Println(string(respBody))

    return
}

感谢http://posttestserver.com 给了我一个可以轻松解决问题的地方!

【讨论】:

    猜你喜欢
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 2011-07-05
    • 2020-07-10
    • 1970-01-01
    • 2018-10-23
    相关资源
    最近更新 更多