是否可以在 GAE Golang Blobstore 中存储任意数据?

我正在 Google App Engine Go 中创建一个大型数据库应用程序。我的大部分数据都很小,所以我将它们存储在 Datastore 中没有问题。但是,我知道我会遇到一些大小为几兆字节的条目,因此我将不得不使用 Blobstore 来保存它们。

在了Blob存储参考,看来该服务的主要目的在于使用的文件被上传到该服务。我需要调用哪些函数来像在 Datastore 中一样在 Blobstore 中存储任意数据?我已经可以将数据转换为 []byte 并且我不需要在 blob 中索引任何东西,只需通过 ID 存储和获取它。


梦里花落0921
浏览 199回答 2
2回答

拉莫斯之舞

有两种方法可以将文件写入 blobstore一种是使用 Blobstore 页面末尾记录的已弃用 API。他们的示例代码如下。他们将要改用的方法是将文件存储在 Google 云存储中并通过 blobstore 为它们提供服务。另一种方法是以某种方式模拟用户上传。Go 有一个 http 客户端,可以将要上传的文件发送到网址。不过,这将是一种黑客方法。var k appengine.BlobKeyw, err := blobstore.Create(c, "application/octet-stream")if err != nil {        return k, err}_, err = w.Write([]byte("... some data ..."))if err != nil {        return k, err}err = w.Close()if err != nil {        return k, err}return w.Key()

LEATH

正如@yumaikas 所说,不推荐使用Files API。如果此数据来自某种用户上传,您应该修改上传表单以使用 Blobstore 上传 URL(特别是,将编码设置为multipart/form-dataormultipart/mixed并命名所有文件上传字段file,除了您不想的那些存储在 blobstore 中)。但是,如果这是不可能的(例如,您无法控制用户输入,或者您必须在将数据存储到 Blobstore 之前在服务器上预处理数据),那么您要么必须使用已弃用的Files API,或使用URLFetch API上传数据。这是一个完整的示例应用程序,它将在 Blobstore 中为您存储一个示例文件。package sampleimport (    "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)    // First you need to create the upload URL:    u, err := blobstore.UploadURL(c, "/upload", nil)    if err != nil {        http.Error(w, err.Error(), http.StatusInternalServerError)        c.Errorf("%s", err)        return    }    // Now you can prepare a form that you will submit to that URL.    var b bytes.Buffer    fw := multipart.NewWriter(&b)    // Do not change the form field, it must be "file"!    // You are free to change the filename though, it will be stored in the BlobInfo.    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    }    // Don't forget to close the multipart writer.    // If you don't close it, your request will be missing the terminating boundary.    fw.Close()    // Now that you have a form, you can submit it to your handler.    req, err := http.NewRequest("POST", u.String(), &b)    if err != nil {        http.Error(w, err.Error(), http.StatusInternalServerError)        c.Errorf("%s", err)        return    }    // Don't forget to set the content type, this will contain the boundary.    req.Header.Set("Content-Type", fw.FormDataContentType())    // Now submit the request.    client := urlfetch.Client(c)    res, err := client.Do(req)    if err != nil {        http.Error(w, err.Error(), http.StatusInternalServerError)        c.Errorf("%s", err)        return    }    // Check the response status, it should be whatever you return in the `/upload` handler.    if res.StatusCode != http.StatusCreated {        http.Error(w, err.Error(), http.StatusInternalServerError)        c.Errorf("bad status: %s", res.Status)        return    }    // Everything went fine.    w.WriteHeader(res.StatusCode)}func Upload(w http.ResponseWriter, r *http.Request) {    c := appengine.NewContext(r)    // Here we just checked that the upload went through as expected.    if _, _, err := blobstore.ParseUpload(r); err != nil {        http.Error(w, err.Error(), http.StatusInternalServerError)        c.Errorf("%s", err)        return    }    // Everything seems fine. Signal the other handler using the status code.    w.WriteHeader(http.StatusCreated)}现在,如果你curl http://localhost:8080/test,它将在 Blobstore 中存储一个文件。重要提示:我不确定您对自己的应用程序发出的请求的带宽费用如何收费。在最坏的情况下,您将被收取内部流量费用,这比正常带宽 iirc 便宜。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go