[golang] golang简洁的文件上传与接收服务

最近自己阿里云上的文件共享总是不怎么方便,本来是用的samba,用着用着就用不乐,见鬼,于是只能自己整个简洁点的了。

不过用go的话也非常快啦。

需要注意的是http post文件一般用的都是multipart表单格式,看一看就好了。

uploadhandle

package main

import (
    "io"
    "io/ioutil"
    "net/http"
    "os"
    "fmt"
)

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    reader, err := r.MultipartReader()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    for {
        part, err := reader.NextPart()
        if err == io.EOF {
            break
        }

        fmt.Printf("FileName=[%s], FormName=[%s]\n", part.FileName(), part.FormName())

        if part.FileName() == "" {//formdata
            data, _ := ioutil.ReadAll(part)
            fmt.Printf("FormData=[%s]\n", string(data))
        } else {
            file, _ := os.Create("./" + part.FileName())
            defer file.Close()
            io.Copy(file, part)
        }
    }
}

func main() {
    http.HandleFunc("/upload", uploadHandler)
    http.ListenAndServe(":8080", nil)
}

upload.go

package main

import (
    "bytes"
    "fmt"
    "io"
    "mime/multipart"
    "net/http"
    "os"
)

func postFile(filename string, target_url string) (*http.Response, error) {
    body_buf := bytes.NewBufferString("")
    body_writer := multipart.NewWriter(body_buf)

    // use the body_writer to write the Part headers to the buffer
    _, err := body_writer.CreateFormFile("userfile", filename)
    if err != nil {
        fmt.Println("error writing to buffer")
        return nil, err
    }

    // the file data will be the second part of the body
    fh, err := os.Open(filename)
    if err != nil {
        fmt.Println("error opening file")
        return nil, err
    }
    // need to know the boundary to properly close the part myself.
    boundary := body_writer.Boundary()
    //close_string := fmt.Sprintf("\r\n--%s--\r\n", boundary)
    close_buf := bytes.NewBufferString(fmt.Sprintf("\r\n--%s--\r\n", boundary))

    // use multi-reader to defer the reading of the file data until
    // writing to the socket buffer.
    request_reader := io.MultiReader(body_buf, fh, close_buf)
    fi, err := fh.Stat()
    if err != nil {
        fmt.Printf("Error Stating file: %s", filename)
        return nil, err
    }
    req, err := http.NewRequest("POST", target_url, request_reader)
    if err != nil {
        return nil, err
	}
	
    // Set headers for multipart, and Content Length
    req.Header.Add("Content-Type", "multipart/form-data; boundary="+boundary)
    req.ContentLength = fi.Size() + int64(body_buf.Len()) + int64(close_buf.Len())

    return http.DefaultClient.Do(req)
}

// sample usage
func main() {
    list := os.Args
    n := len(list)
    if n != 2 {
        return
    }
    target_url := "http://127.0.0.1:8080/upload"
    filename := list[1]
    postFile(filename, target_url)
}

你可能感兴趣的:(Go从入门到入土,后端笔记,Go,http,file,server,http,golang,文件接收)