golang-upload-and-Receive-file

Source: Internet
Author: User
Tags http post
This is a creation in Article, where the information may have evolved or changed.
Package Mainimport ("FMT" "io" "net/http" "Log")//Get the size of an excuse type Sizer interface {size () int64}//Hello wor LD, the Web serverfunc helloserver (w http. Responsewriter, R *http. Request) {if "POST" = = R.method {file, _, Err: = R.formfile ("UserFile") if err! = Nil {http. Error (W, err. Error (), +) return} defer file. Close () F,err:=os. Create ("Filenametosaveas") defer f.close () io. Copy (F,file) fmt. fprintf (w, "Upload file Size:%d", file.) Sizer). Size ()) return}//upload page W.header (). ADD ("Content-type", "text/html") W.writeheader (HTML): = ' <form enctype= ' multipart/form-data ' action= '/hello ' method= "POST" > Send this file: <input name= "UserFile" type= "file"/> <input type= "Submit" value= "Send Fi" Le "/></form> ' io. WriteString (w, HTML)}func Main () {http. Handlefunc ("/hello", HelloServer) Err: = http. Listenandserve (": 12345", nil) if err! = Nil {log. Fatal ("Listenandserve:", Err)}} The client uploads the textCode: Func Upload () (err error) {//Create buffer buf: = new (bytes. Buffer)///caveat IMO dont use this for large files, \//Create a tmpfile and assemble your multipart from there (not Tested) W: = multipart. Newwriter (BUF)//Create file field fw, err: = W.createformfile ("File", "Helloworld.go")//file Here is important, must and server-side FORMFI Le consistent if err! = Nil {fmt. Println ("C") return err} FD, err: = OS. Open ("Helloworld.go") if err! = Nil {fmt. Println ("D") return err} defer FD. Close ()//Write file field from file to upload _, err = Io. Copy (FW, FD) if err! = Nil {fmt. Println ("E") return err}//Important If you don't close the multipart writer you won't have A//Termina Ting Boundry w.close () req, err: = http. Newrequest ("POST", "http://192.168.2.127/configure.go?portId=2", buf) if err! = Nil {fmt. Println ("F") return err} req. Header.set ("Content-type", W.formdatacontenttype ()) var client http. ClienT res, err: = client. Do (req) if err! = Nil {fmt. Println ("G") return err} io. Copy (OS. Stderr, Res. Body)//Replace this with Status.code check FMT. Println ("H") return err}

Handling file Uploads

You want to work with a user-uploaded file, for example, you're building a website like Instagram, and you need to store the photos taken by the user. How does this need to be achieved?

To enable a form to upload a file, the first step is to add the properties of the form enctype , enctype with the following three scenarios:

Application/x-www-form-urlencoded means all characters are encoded before sending (default)

Multipart/form-data characters are not encoded. You must use this value when you use a form that contains a file upload control.

The Text/plain space is converted to the "+" plus sign, but does not encode special characters.

Therefore, the HTML code for the form should look like this:

On the server side, we add a handlerfunc:

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)        if err != nil {            fmt.Println(err)            return        }        defer f.Close()        io.Copy(f, file)    }}

As you can see from the code above, we need to call to process file uploads r.ParseMultipartForm ,

The parameters inside indicate maxMemory that, ParseMultipartForm after the call,

The uploaded file is stored in the maxMemory size of the memory, if the file size exceeds maxMemory , then the remainder will be stored in the system's temporary files.

We can r.FormFile store the file by getting the file handle above and then using it in the instance io.Copy .

You don't need to call when you get other non-file field information r.ParseForm , because go automatically calls when needed. And once ParseMultipartForm called once, the subsequent call will no longer be effective.

Through the above example we can see that we upload the file main three-step processing:

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

File handler is multipart. Fileheader, which stores the following structure information

type FileHeader struct {Filename stringHeader   textproto.MIMEHeader// contains filtered or unexported fields}

We print out the above example code to upload the file information as follows

![](images/4.5.upload2.png?raw=true)

Server-side accepted information after printing a file upload

Client upload File

Our example above demonstrates how to upload a file from a form and then process the file on the server side,

In fact, go support the Simulation client form feature support file upload, detailed usage see the following example:

Package Mainimport ("bytes" "FMT" "io" "io/ioutil" "Mime/multipart" "Net/http" "OS") func postfile (filename string, TargetUrl string) Error {bodybuf: = &bytes. buffer{} bodywriter: = multipart.         Newwriter (BODYBUF)//Critical one-step operation FileWriter, err: = Bodywriter.createformfile ("UploadFile", filename) if err! = Nil { Fmt. PRINTLN ("Error writing to buffer") return err}//Open file handle operation FH, err: = OS. Open (filename) if err! = Nil {fmt. PRINTLN ("Error opening file") Return err}//iocopy _, err = Io. Copy (FileWriter, FH) if err! = Nil {return err} ContentType: = Bodywriter.formdatacontenttype () bodyw Riter. 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 Usagefunc main (){target_url: = "http://localhost:9090/upload" FileName: = "./astaxie.pdf" postfile (filename, Target_url)} 

The example above shows a detailed example of how a client uploads a file to the server,

The client passes the multipart. Write writes the text stream of the file to a cache, and then calls the HTTP POST method to upload the cache to the server.

If you have other common fields such as username that need to be written at the same time, you can call multipart's Writefield method to write many other similar fields.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.