最近自己阿里云上的文件共享总是不怎么方便,本来是用的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)
}
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 := ("\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)
}