**单文件上传** 服务端代码: 写法一: ~~~ package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) func main() { router := gin.Default() // Set a lower memory limit for multipart forms (default is 32 MiB) // router.MaxMultipartMemory = 8 << 20 // 8 MiB router.POST("/upload", func(c *gin.Context) { file, err := c.FormFile("filename") if err != nil { c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error())) return } file.Filename = "copy_" + file.Filename if err := c.SaveUploadedFile(file, file.Filename); err != nil { c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error())) return } c.String(http.StatusOK, fmt.Sprintf("File %s uploaded success", file.Filename)) }) router.Run(":8000") } ~~~ 写法二: ~~~ package main import ( "fmt" "io" "log" "net/http" "os" "github.com/gin-gonic/gin" ) // 接收client上传的文件 // 从FormFile中获取相关的文件data! // 然后写入本地文件 func upload(c *gin.Context) { // 注意此处的文件名和client处的应该是一样的 file, header, err := c.Request.FormFile("uploadFile") filename := header.Filename fmt.Println(header.Filename) // 创建临时接收文件 out, err := os.Create("copy_" + filename) if err != nil { log.Fatal(err) } defer out.Close() // Copy数据 _, err = io.Copy(out, file) if err != nil { log.Fatal(err) } c.String(http.StatusOK, "upload file success") } func main() { router := gin.Default() // 接收上传的文件,需要使用 router.POST("/upload", upload) router.Run(":8000") } ~~~ 客户端代码: ~~~ package main import ( "bytes" "fmt" "io" "io/ioutil" "mime/multipart" "net/http" "os" ) func main() { // 上传文件POST // 下面构造一个文件buf作为POST的BODY buf := new(bytes.Buffer) w := multipart.NewWriter(buf) fw, _ := w.CreateFormFile("uploadFile", "xxx.jpg") //这里的uploadFile必须和服务器端的FormFile-name一致 fd, _ := os.Open("xxx.jpg") defer fd.Close() io.Copy(fw, fd) w.Close() resp, _ := http.Post("http://0.0.0.0:8000/upload", w.FormDataContentType(), buf) helpRead(resp) } // 用于读取resp的body func helpRead(resp *http.Response) { defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("ERROR2!: ", err) } fmt.Println(string(body)) } ~~~ **多文件上传** ~~~ package main import ( "fmt" "net/http" "github.com/gin-gonic/gin" ) func main() { router := gin.Default() // Set a lower memory limit for multipart forms (default is 32 MiB) // router.MaxMultipartMemory = 8 << 20 // 8 MiB // router.Static("/", "./public") router.POST("/upload", func(c *gin.Context) { // Multipart form form, err := c.MultipartForm() if err != nil { c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error())) return } files := form.File["files"] for _, file := range files { if err := c.SaveUploadedFile(file, file.Filename); err != nil { c.String(http.StatusBadRequest, fmt.Sprintf("upload file err: %s", err.Error())) return } } c.String(http.StatusOK, fmt.Sprintf("Uploaded successfully %d files ", len(files))) }) router.Run(":8000") } ~~~ **日志文件** ~~~ package main import ( "io" "os" "github.com/gin-gonic/gin" ) func main() { // Disable Console Color, you don't need console color when writing the logs to file. gin.DisableConsoleColor() // Logging to a file. f, _ := os.Create("gin.log") gin.DefaultWriter = io.MultiWriter(f) // Use the following code if you need to write the logs to file and console at the same time. // gin.DefaultWriter = io.MultiWriter(f, os.Stdout) router := gin.Default() router.GET("/ping", func(c *gin.Context) { c.String(200, "pong") }) router.Run(":8000") } ~~~