我正在玩Mux和net/http
。最近,我试图获得一个带有一个端点的简单服务器来接受文件上传。
这是我到目前为止的代码:
server.go
package main
import (
"fmt"
"github.com/gorilla/mux"
"log"
"net/http"
)
func main() {
router := mux.NewRouter()
router.
Path("/upload").
Methods("POST").
HandlerFunc(UploadCsv)
fmt.Println("Starting")
log.Fatal(http.ListenAndServe(":8080", router))
}
endpoint.go
package main
import (
"fmt"
"net/http"
)
func UploadFile(w http.ResponseWriter, r *http.Request) {
err := r.ParseMultipartForm(5 * 1024 * 1024)
if err != nil {
panic(err)
}
fmt.Println(r.FormValue("fileupload"))
}
我认为我已经将问题缩小到实际从UploadFile
内的请求中检索正文。当我运行这个cURL命令时:
curl http://localhost:8080/upload -F "fileupload=@test.txt" -vvv
我得到一个空响应(正如预期;我不打印到ResponseWriter
),但我只是在我正在运行服务器的提示符处打印一个新的(空)行,而不是请求机构。
我将文件作为multipart发送(AFAIK,在cURL中使用-F
隐含而不是-d
),并且cURL的详细输出显示已发送502个字节:
$ curl http://localhost:8080/upload -F "fileupload=@test.txt" -vvv
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /upload HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.51.0
> Accept: */*
> Content-Length: 520
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------b578878d86779dc5
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Fri, 18 Nov 2016 19:01:50 GMT
< Content-Length: 0
< Content-Type: text/plain; charset=utf-8
<
* Curl_http_done: called premature == 0
* Connection #0 to host localhost left intact
使用Go中的net/http
服务器接收作为多部分表单数据上传的文件的正确方法是什么?
答案 0 :(得分:17)
这是一个简单的例子
func ReceiveFile(w http.ResponseWriter, r *http.Request) {
var Buf bytes.Buffer
// in your case file would be fileupload
file, header, err := r.FormFile("file")
if err != nil {
panic(err)
}
defer file.Close()
name := strings.Split(header.Filename, ".")
fmt.Printf("File name %s\n", name[0])
// Copy the file data to my buffer
io.Copy(&Buf, file)
// do something with the contents...
// I normally have a struct defined and unmarshal into a struct, but this will
// work as an example
contents := Buf.String()
fmt.Println(contents)
// I reset the buffer in case I want to use it again
// reduces memory allocations in more intense projects
Buf.Reset()
// do something else
// etc write header
return
}
答案 1 :(得分:10)
您应该使用FormFile
代替FormValue
:
file, handler, err := r.FormFile("fileupload")
defer file.Close()
// copy example
f, err := os.OpenFile("./downloaded", os.O_WRONLY|os.O_CREATE, 0666)
defer f.Close()
io.Copy(f, file)
答案 2 :(得分:2)
这是我编写的帮助我上传文件的功能。您可以在此处查看完整版本。 How to upload files in golang
package helpers
import (
"net/http"
"os"
"io"
)
func FileUpload(r *http.Request) (string, error) {
//this function returns the filename(to save in database) of the saved file or an error if it occurs
r.ParseMultipartForm(32 << 20)
//ParseMultipartForm parses a request body as multipart/form-data
var file_name string
var errors error
file, handler, err := r.FormFile("file")//retrieve the file from form data
defer file.Close() //close the file when we finish
if err != nil {
errors = err
}
//this is path which we want to store the file
f, err := os.OpenFile("./images/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
errors = err
}
file_name = handler.Filename
defer f.Close()
io.Copy(f, file)
//here we save our file to our path
return file_name, errors
}