正如@yumaikas所说,
Files API已被弃用。如果这些数据来自某种用户上传,您应该修改上传表单以使用Blobstore上传URL(特别是将编码设置为
multipart/form-data
或
multipart/mixed
并将所有文件上传字段命名为
file
,除了不想存储在Blobstore中的那些字段)。
但是,如果不可能实现上述修改(例如,您无法控制用户输入,或者必须在将其存储在Blobstore之前在服务器上预处理数据),则必须使用已弃用的
Files API或使用
URLFetch API上传数据。
以下是一个完整的示例应用程序,可为您在Blobstore中存储一个样本文件。
package sample
import (
"bytes"
"net/http"
"mime/multipart"
"appengine"
"appengine/blobstore"
"appengine/urlfetch"
)
const SampleData = `foo,bar,spam,eggs`
func init() {
http.HandleFunc("/test", StoreSomeData)
http.HandleFunc("/upload", Upload)
}
func StoreSomeData(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
u, err := blobstore.UploadURL(c, "/upload", nil)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("%s", err)
return
}
var b bytes.Buffer
fw := multipart.NewWriter(&b)
file, err := fw.CreateFormFile("file", "example.csv")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("%s", err)
return
}
if _, err = file.Write([]byte(SampleData)); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("%s", err)
return
}
fw.Close()
req, err := http.NewRequest("POST", u.String(), &b)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("%s", err)
return
}
req.Header.Set("Content-Type", fw.FormDataContentType())
client := urlfetch.Client(c)
res, err := client.Do(req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("%s", err)
return
}
if res.StatusCode != http.StatusCreated {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("bad status: %s", res.Status)
return
}
w.WriteHeader(res.StatusCode)
}
func Upload(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
if _, _, err := blobstore.ParseUpload(r); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
c.Errorf("%s", err)
return
}
w.WriteHeader(http.StatusCreated)
}
现在,如果你运行
curl http://localhost:8080/test
命令,它会将一个文件存储到Blobstore中。
重要提示:我不确定您如何为向自己的应用程序发出的请求计费。在最坏的情况下,您将被收取内部流量费用,这比普通带宽便宜。