如何在Golang中实现文件上传进度显示

答案:通过自定义ProgressReader包装文件流,在读取时实时统计已上传字节数并回调更新进度,结合multipart上传实现golang文件上传进度显示。

如何在Golang中实现文件上传进度显示

golang中实现文件上传进度显示,关键在于监控上传过程中已发送的数据量。标准的 net/http 包本身不提供进度回调机制,因此需要通过自定义 io.Reader 来实现对数据读取过程的拦截和统计。

1. 使用带进度的Reader包装原始文件

核心思路是创建一个包装了原文件的 io.Reader,在每次读取时更新已上传字节数,并调用回调函数显示进度。

示例代码:

package main  import (     "fmt"     "io"     "mime/multipart"     "net/http"     "os"     "sync" )  // ProgressReader 记录上传进度 type ProgressReader struct {     file     *os.File     total    int64     read     int64     callback func(read, total int64)     mu       sync.Mutex }  func (pr *ProgressReader) Read(p []byte) (n int, err error) {     n, err = pr.file.Read(p)     pr.mu.Lock()     pr.read += int64(n)     pr.callback(pr.read, pr.total)     pr.mu.Unlock()     return n, err }  func (pr *ProgressReader) Close() error {     return pr.file.Close() } 

2. 构造带进度的HTTP请求

使用 multipart/form-data 格式上传文件,在构建请求体时将原始文件替换为 ProgressReader

如何在Golang中实现文件上传进度显示

百度文心百中

百度大模型语义搜索体验中心

如何在Golang中实现文件上传进度显示22

查看详情 如何在Golang中实现文件上传进度显示

func uploadFileWithProgress(filepath, url string) error {     file, err := os.Open(filepath)     if err != nil {         return err     }     defer file.Close()      fileInfo, _ := file.Stat()     total := fileInfo.Size()      body := &bytes.Buffer{}     writer := multipart.NewWriter(body)      // 创建带进度的Reader     progressReader := &ProgressReader{         file:  file,         total: total,         callback: func(read, total int64) {             fmt.Printf("r上传进度: %d/%d (%.2f%%)",                  read, total, float64(read)/float64(total)*100)         },     }      part, err := writer.CreateFormFile("upload", filepath)     if err != nil {         return err     }      _, err = io.Copy(part, progressReader)     if err != nil {         return err     }     writer.Close()      req, err := http.NewRequest("POST", url, body)     if err != nil {         return err     }     req.Header.Set("Content-Type", writer.FormDataContentType())      client := &http.Client{}     resp, err := client.Do(req)     if err != nil {         return err     }     defer resp.Body.Close()      fmt.Println("n上传完成")     return nil } 

3. 调用上传函数

只需调用封装好的函数即可看到实时进度输出。

立即学习go语言免费学习笔记(深入)”;

func main() {     err := uploadFileWithProgress("./example.zip", "https://httpbin.org/post")     if err != nil {         fmt.Println("上传失败:", err)     } } 

这种方式适用于客户端主动上传文件的场景。如果是在服务端接收大文件并想通知前端进度,则需结合数据库redis记录状态,并通过websocket或轮询方式推送进度。

基本上就这些,核心就是用一个中间层Reader来“监听”数据流动。

上一篇
下一篇
text=ZqhQzanResources