zoukankan      html  css  js  c++  java
  • golang文件上传

    1.上传文件主要三步处理:

    表单中增加enctype="multipart/form-data"
    服务端调用r.ParseMultipartForm,把上传的文件存储在内存和临时文件中
    使用r.FormFile获取文件句柄,然后对文件进行存储等处理。

    // 示例代码
    r.ParseMultipartForm(32 << 20)
    file, handler, err := r.FormFile("uploadfile")
    defer file.Close()
    f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) 
    defer f.Close()
    io.Copy(f, file)
    

    2.客户端上传文件

    package main
    
    import (
    	"bytes"
    	"fmt"
    	"io"
    	"io/ioutil"
    	"mime/multipart"
    	"net/http"
    	"os"
    )
    
    func postFile(filename string, targetUrl string) error {
    	bodyBuf := &bytes.Buffer{}
    	bodyWriter := multipart.NewWriter(bodyBuf)
    
    	//关键的一步操作
    	fileWriter, err := bodyWriter.CreateFormFile("uploadfile", filename)
    	if err != nil {
    		fmt.Println("error writing to buffer")
    		return err
    	}
    
    	//打开文件句柄操作
    	fh, err := os.Open(filename)
    	if err != nil {
    		fmt.Println("error opening file")
    		return err
    	}
    	defer fh.Close()
    	
    	//iocopy
    	_, err = io.Copy(fileWriter, fh)
    	if err != nil {
    		return err
    	}
    
    	contentType := bodyWriter.FormDataContentType()
    	bodyWriter.Close()
    
    	resp, err := http.Post(targetUrl, contentType, bodyBuf)
    	if err != nil {
    		return err
    	}
    	defer resp.Body.Close()
    	resp_body, err := ioutil.ReadAll(resp.Body)
    	if err != nil {
    		return err
    	}
    	fmt.Println(resp.Status)
    	fmt.Println(string(resp_body))
    	return nil
    }
    
    // sample usage
    func main() {
    	target_url := "http://localhost:9090/upload"
    	filename := "./astaxie.pdf"
    	postFile(filename, target_url)
    }
    

    3.服务端处理上传文件

    http.HandleFunc("/upload", upload)
    
    // 处理/upload 逻辑
    func upload(w http.ResponseWriter, r *http.Request) {
    	fmt.Println("method:", r.Method) //获取请求的方法
    	if r.Method == "GET" {
    		crutime := time.Now().Unix()
    		h := md5.New()
    		io.WriteString(h, strconv.FormatInt(crutime, 10))
    		token := fmt.Sprintf("%x", h.Sum(nil))
    
    		t, _ := template.ParseFiles("upload.gtpl")
    		t.Execute(w, token)
    	} else {
    		r.ParseMultipartForm(32 << 20)
    		file, handler, err := r.FormFile("uploadfile")
    		if err != nil {
    			fmt.Println(err)
    			return
    		}
    		defer file.Close()
    		fmt.Fprintf(w, "%v", handler.Header)
    		f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)  // 此处假设当前目录下已存在test目录
    		if err != nil {
    			fmt.Println(err)
    			return
    		}
    		defer f.Close()
    		io.Copy(f, file)
    	}
    }
    
  • 相关阅读:
    Socket与系统调用深度分析
    AudioRecord::getMinFrameCount
    c++: address argument to atomic operation must be a pointer to _Atomic type
    python秒表,方便测试计时
    Android驱动笔记(13)——PMIC reset介绍
    Android驱动笔记(10)——DOS或BAT脚本语法
    第八章——Linux设备模型(1)
    第四章——IOCTL(1)
    第三章(扩展)——虚拟串口设备
    第三章——字符驱动设备
  • 原文地址:https://www.cnblogs.com/tomtellyou/p/12599123.html
Copyright © 2011-2022 走看看