web-dev-qa-db-ja.com

Golang net / httpサーバーを使用してアップロードされたファイルを受信するにはどうすればよいですか?

Mux およびnet/httpで遊んでいます。最近、ファイルのアップロードを受け入れる1つのエンドポイントを持つ単純なサーバーを取得しようとしています。

これが私がこれまでに手に入れたコードです。

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 "[email protected]" -vvv

空の応答を受け取ります(予想どおり、ResponseWriterに出力しません)が、要求の代わりに、サーバーを実行しているプロンプトで新しい(空の)行が出力されます。体。

私はファイルをマルチパートとして送信しています(cURLで-Fではなく-dを使用することで暗示されています)、cURLの詳細な出力は送信された502バイトを示しています。

$ curl http://localhost:8080/upload -F "[email protected]" -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サーバーを使用してマルチパートフォームデータとしてアップロードされたファイルを受信する適切な方法は何ですか?

25
user7179784

ここに簡単な例があります

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
}
21
reticentroot

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)
11
Alex Pliutau

ここに、ファイルのアップロードを支援するために作成した関数があります。ここで完全版を確認できます。 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
  }
2
keith wachira