iris多文件上传示例

目录结构

主目录uploadFiles

  1. —— templates
  2. —— upload_form.html
  3. —— uploads
  4. —— main.go

示例代码

/templates/upload_form.html

  1. <html>
  2. <head>
  3. <title>Upload file</title>
  4. </head>
  5. <body>
  6. <form enctype="multipart/form-data"
  7. action="http://127.0.0.1:8080/upload" method="POST">
  8. <input type="file" name="uploadfile" multiple/> <input type="hidden"
  9. name="token" value="{{.}}" /> <input type="submit" value="upload" />
  10. </form>
  11. </body>
  12. </html>

main.go

  1. package main
  2. import (
  3. "crypto/md5"
  4. "fmt"
  5. "io"
  6. "mime/multipart"
  7. "os"
  8. "path/filepath"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "github.com/kataras/iris"
  13. )
  14. func main() {
  15. app := iris.New()
  16. app.RegisterView(iris.HTML("./templates", ".html"))
  17. //将upload_form.html提供给客户端
  18. app.Get("/upload", func(ctx iris.Context) {
  19. //创建一个令牌(可选)。
  20. now := time.Now().Unix()
  21. h := md5.New()
  22. io.WriteString(h, strconv.FormatInt(now, 10))
  23. token := fmt.Sprintf("%x", h.Sum(nil))
  24. //使用令牌渲染表单以供您使用
  25. ctx.View("upload_form.html", token)
  26. })
  27. //处理来自upload_form.html的请求
  28. app.Post("/upload", func(ctx iris.Context) {
  29. //上传任意数量的文件(表单输入中的multiple属性)。
  30. //第二个参数完全是可选的,它可以用来根据请求更改文件的名称,
  31. //在这个例子中,我们将展示如何使用它,通过在上传文件前加上当前用户的ip前缀
  32. ctx.UploadFormFiles("./uploads", beforeSave)
  33. })
  34. app.Post("/upload_manual", func(ctx iris.Context) {
  35. //获取通过iris.WithPostMaxMemory获取的最大上传值大小。
  36. maxSize := ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()
  37. err := ctx.Request().ParseMultipartForm(maxSize)
  38. if err != nil {
  39. ctx.StatusCode(iris.StatusInternalServerError)
  40. ctx.WriteString(err.Error())
  41. return
  42. }
  43. form := ctx.Request().MultipartForm
  44. files := form.File["files[]"]
  45. failures := 0
  46. for _, file := range files {
  47. _, err = saveUploadedFile(file, "./uploads")
  48. if err != nil {
  49. failures++
  50. ctx.Writef("failed to upload: %s\n", file.Filename)
  51. }
  52. }
  53. ctx.Writef("%d files uploaded", len(files)-failures)
  54. })
  55. //在http://localhost:8080启动服务器,上传限制为32 MB。
  56. app.Run(iris.Addr(":8080"), iris.WithPostMaxMemory(32<<20))
  57. }
  58. func saveUploadedFile(fh *multipart.FileHeader, destDirectory string) (int64, error) {
  59. src, err := fh.Open()
  60. if err != nil {
  61. return 0, err
  62. }
  63. defer src.Close()
  64. out, err := os.OpenFile(filepath.Join(destDirectory, fh.Filename),
  65. os.O_WRONLY|os.O_CREATE, os.FileMode(0666))
  66. if err != nil {
  67. return 0, err
  68. }
  69. defer out.Close()
  70. return io.Copy(out, src)
  71. }
  72. func beforeSave(ctx iris.Context, file *multipart.FileHeader) {
  73. ip := ctx.RemoteAddr()
  74. //确保以某种方式格式化ip
  75. //可以用于文件名(简单情况):
  76. ip = strings.Replace(ip, ".", "_", -1)
  77. ip = strings.Replace(ip, ":", "_", -1)
  78. //你可以使用time.Now,为文件添加前缀或后缀
  79. //基于当前时间戳。
  80. //即unixTime := time.Now().Unix()
  81. //使用$IP-为Filename添加前缀
  82. //不需要更多动作,内部上传者将使用此功能
  83. //将文件保存到"./uploads"文件夹中的名称。
  84. file.Filename = ip + "-" + file.Filename
  85. }