Golang 上传下载

Go 实现上传下载功能

上传

单文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

func main() {
router := gin.Default()
// 给表单限制上传大小 (默认 32 MiB)
// router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单文件
file, _ := c.FormFile("file")
log.Println(file.Filename)

// 上传文件到指定的路径
c.SaveUploadedFile(file, "./test.xmind")

c.String(http.StatusOK, fmt.Sprintf("uploaded!"))
})
router.Run(":8080")
}

多文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

func main() {
router := gin.Default()
// 给表单限制上传大小 (默认 32 MiB)
// router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 多文件
form, _ := c.MultipartForm()
// form-data 的 key 值就是 "upload[]" 括号不能省略
files := form.File["upload[]"]

for _, file := range files {
log.Println(file.Filename)

// 上传文件到指定的路径
c.SaveUploadedFile(file, "./"+file.Filename)
}
c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
})
router.Run(":8080")
}

下载

直接下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

func main() {
router := gin.Default()

router.GET("/download", func(c *gin.Context) {
c.Header("Content-Type", "application/octet-stream")
// filename 中文乱码问题 filename*=utf-8''xxx
//disposition := fmt.Sprintf("attachment; filename*=utf-8''%s", url.QueryEscape("工作簿1.xlsx"))
disposition := "attachment; filename=下载测试.xlsx"
c.Header("Content-Disposition", disposition)
//file, err := ioutil.ReadFile("../../PostgreSQL数据库内核分析.pdf")
file, err := ioutil.ReadFile("../../工作簿1.xlsx")
if err != nil {
log.Println(err)
}
c.Writer.Write(file)
})

router.Run(":8080")
}

展示文件,手动下载(适合PDF等文件)

1
2
3
4
5
6
7
8
9
10

func main() {
router := gin.Default()

router.GET("/download", func(c *gin.Context) {
c.File("../../PostgreSQL数据库内核分析.pdf")
})
router.Run(":8080")
}

限速下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

func main() {
router := gin.Default()

router.GET("/download", func(c *gin.Context) {
file, err := os.Open("../../工作簿1.xlsx")
if err != nil {
log.Println(err)
}
defer file.Close()

//读取文件头部信息
fileHeader := make([]byte, 512)
file.Read(fileHeader) //取出文件头部信息

fileStat, _ := file.Stat()

//c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Type", http.DetectContentType(fileHeader)) //返回检测到的文件类型
c.Header("Content-Length", strconv.FormatInt(fileStat.Size(), 10)) //返回文件大小
// filename 中文乱码问题 filename*=utf-8''xxx
//disposition := fmt.Sprintf("attachment; filename*=utf-8''%s", url.QueryEscape("工作簿1.xlsx"))
disposition := "attachment; filename=下载测试.xlsx"
c.Header("Content-Disposition", disposition)

//file.Seek(0, 0)
//io.Copy(c.Writer, file)
c.Writer.Write(fileHeader)
for {
tmp := make([]byte, 1000) //通过切片长度控制流速
n, err := file.Read(tmp)
if err == io.EOF {
return
}
c.Writer.Write(tmp[:n])
time.Sleep(time.Second * 1) //通过sleep时间控制流速
}
})

router.Run(":8080")
}