服务器端:

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "strings"
  7. "time"
  8. "crypto/md5"
  9. "io"
  10. "strconv"
  11. "os"
  12. )
  13. func upload(w http.ResponseWriter, r *http.Request) {
  14. fmt.Println("method:", r.Method) //获取请求的方法
  15. if r.Method == "GET" {
  16. crutime := time.Now().Unix()
  17. h := md5.New()
  18. io.WriteString(h, strconv.FormatInt(crutime, 10))
  19. token := fmt.Sprintf("%x", h.Sum(nil))
  20. t, _ := template.ParseFiles("upload.gtpl")
  21. t.Execute(w, token)
  22. } else {
  23. r.ParseMultipartForm(32 << 20)
  24. file, handler, err := r.FormFile("uploadfile")
  25. if err != nil {
  26. fmt.Println(err)
  27. return
  28. }
  29. defer file.Close()
  30. fmt.Fprintf(w, "%v", handler.Header)
  31. f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) // 此处假设当前目录下已存在test目录
  32. if err != nil {
  33. fmt.Println(err)
  34. return
  35. }
  36. defer f.Close()
  37. io.Copy(f, file)
  38. }
  39. }
  40. func main() {
  41. http.HandleFunc("/upload", upload)
  42. err := http.ListenAndServe(":8080", nil) //设置监听的端口
  43. if err != nil {
  44. log.Fatal("ListenAndServe: ", err)
  45. }
  46. }

其实Go支持模拟客户端表单功能支持文件上传,详细用法请看如下示例:
客户端代码:

  1. package main
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "mime/multipart"
  8. "net/http"
  9. "os"
  10. )
  11. func postFile(filename string, targetUrl string) error {
  12. bodyBuf := &bytes.Buffer{}
  13. bodyWriter := multipart.NewWriter(bodyBuf)
  14. //关键的一步操作
  15. fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename)
  16. if err != nil {
  17. fmt.Println("error writing to buffer")
  18. return err
  19. }
  20. //打开文件句柄操作
  21. fh, err := os.Open(filename)
  22. if err != nil {
  23. fmt.Println("error opening file")
  24. return err
  25. }
  26. defer fh.Close()
  27. //iocopy
  28. _, err = io.Copy(fileWriter, fh)
  29. if err != nil {
  30. return err
  31. }
  32. contentType := bodyWriter.FormDataContentType()
  33. bodyWriter.Close()
  34. resp, err := http.Post(targetUrl, contentType, bodyBuf)
  35. if err != nil {
  36. return err
  37. }
  38. defer resp.Body.Close()
  39. resp_body, err := ioutil.ReadAll(resp.Body)
  40. if err != nil {
  41. return err
  42. }
  43. fmt.Println(resp.Status)
  44. fmt.Println(string(resp_body))
  45. return nil
  46. }
  47. // sample usage
  48. func main() {
  49. target_url := "http://localhost:8080/upload"
  50. filename := "./test.png"
  51. postFile(filename, target_url)
  52. }

分类: web

标签:   golang