文件上传

文件上传的功能比较常用,我们来看一个使用gf框架的WebServer服务端处理文件上传的例子:

  1. package main
  2. import (
  3. "github.com/gogf/gf/frame/g"
  4. "github.com/gogf/gf/net/ghttp"
  5. "github.com/gogf/gf/os/gfile"
  6. "io"
  7. )
  8. // Upload uploads file to /tmp .
  9. func Upload(r *ghttp.Request) {
  10. f, h, e := r.FormFile("upload-file")
  11. if e != nil {
  12. r.Response.Write(e)
  13. }
  14. defer f.Close()
  15. savePath := "/tmp/" + gfile.Basename(h.Filename)
  16. file, err := gfile.Create(savePath)
  17. if err != nil {
  18. r.Response.Write(err)
  19. return
  20. }
  21. defer file.Close()
  22. if _, err := io.Copy(file, f); err != nil {
  23. r.Response.Write(err)
  24. return
  25. }
  26. r.Response.Write("upload successfully")
  27. }
  28. // UploadShow shows uploading page.
  29. func UploadShow(r *ghttp.Request) {
  30. r.Response.Write(`
  31. <html>
  32. <head>
  33. <title>GF UploadFile Demo</title>
  34. </head>
  35. <body>
  36. <form enctype="multipart/form-data" action="/upload" method="post">
  37. <input type="file" name="upload-file" />
  38. <input type="submit" value="upload" />
  39. </form>
  40. </body>
  41. </html>
  42. `)
  43. }
  44. func main() {
  45. s := g.Server()
  46. s.Group("/upload", func(group *ghttp.RouterGroup) {
  47. group.ALL("/", Upload)
  48. group.ALL("/show", UploadShow)
  49. })
  50. s.SetPort(8199)
  51. s.Run()
  52. }

访问 http://127.0.0.1:8199/upload/show 选择需要上传的文件,提交之后可以看到文件上传成功到服务器上。

服务端处理文件上传比较简单,但是需要注意以下几点:

  1. 服务端在上传处理中需要使用defer f.Close()关闭掉临时上传文件指针;
  2. 将上传文件转存到其他文件目录时,需要通过gfile.Create新建文件,并通过io.Copy(file, f)将文件内存写入到新文件中,这里使用的是流式读写方式,就算上传的文件容量有数G,也丝毫不会影响服务端的内存占用;
  3. 需要使用defer file.Close()关闭创建的文件指针;

HTTP客户端上传文件的例子请参考后续的【HTTP客户端-使用示例】章节