Gin模拟大文件上传 分片存储 分片显示

package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.New()
	r.Use(func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				c.AbortWithStatusJSON(400, gin.H{"err": err})
			}
		}()
		c.Next()
	})
	r.GET("/", func(c *gin.Context) {
		c.Writer.Header().Set("Content-Type", "image/png")
		c.Writer.Header().Set("Transfer-Encoding", "chunked")
		// 模拟读取分片 读取分布式服务器中文件的分片数据
		for i := 0; i < 5; i++ {
			f, _ := os.Open(fmt.Sprintf("./files/img_%d.png", i))
			b, _ := ioutil.ReadAll(f)
			c.Writer.Write(b)
			c.Writer.(http.Flusher).Flush()
		}
	})
	r.POST("/file", func(c *gin.Context) {
		file, head, _ := c.Request.FormFile("file")
		block := head.Size / 5 // 模拟分片
		index := 0
		for {
			buf := make([]byte, block)
			n, err := file.Read(buf)
			if err != nil && err != io.EOF {
				panic(err.Error())
			}
			if n == 0 {
				break
			}
			saveBlock(fmt.Sprintf("img_%d.png", index), buf)
			index++
		}
		c.JSON(200, gin.H{"message": "OK"})
	})
	r.Run(":8080")
}

func saveBlock(name string, buf []byte) {
	save, _ := os.OpenFile("./files/"+name, os.O_CREATE|os.O_RDWR, 0600)
	defer save.Close()
	save.Write(buf)
}

最后更新于