简介
Go提供的net/http
和mime/multipart
两个包可以很容易的实现http文件上传。
客户端
package main
import (
"bytes"
"io"
"log"
"mime/multipart"
"net/http"
"os"
)
func main() {
// 创建表单文件
// CreateFormFile 用来创建表单,第一个参数是字段名,第二个参数是文件名
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
formFile, err := writer.CreateFormFile("uploadfile", "test.jpg")
if err != nil {
log.Fatalf("Create form file failed: %s\n", err)
}
// 从文件读取数据,写入表单
srcFile, err := os.Open("test.jpg")
if err != nil {
log.Fatalf("%Open source file failed: s\n", err)
}
defer srcFile.Close()
_, err = io.Copy(formFile, srcFile)
if err != nil {
log.Fatalf("Write to form file falied: %s\n", err)
}
// 发送表单
contentType := writer.FormDataContentType()
writer.Close() // 发送之前必须调用Close()以写入结尾行
_, err = http.Post("http://localhost:9090/upload", contentType, buf)
if err != nil {
log.Fatalf("Post failed: %s\n", err)
}
}
服务器端
package main
import (
"io"
"log"
"net/http"
"os"
)
func main() {
http.HandleFunc("/upload", uploadHandle)
log.Fatal(http.ListenAndServe(":9090", nil))
}
func uploadHandle(w http.ResponseWriter, r *http.Request) {
// 根据字段名获取表单文件
formFile, header, err := r.FormFile("uploadfile")
if err != nil {
log.Printf("Get form file failed: %s\n", err)
return
}
defer formFile.Close()
// 创建保存文件
destFile, err := os.Create("." + r.URL.Path + "/" + header.Filename)
if err != nil {
log.Printf("Create failed: %s\n", err)
return
}
defer destFile.Close()
// 读取表单文件,写入保存文件
_, err = io.Copy(destFile, formFile)
if err != nil {
log.Printf("Write file failed: %s\n", err)
return
}
}