讀取及寫入 Cloud Storage

本文件說明如何使用 Cloud Storage 用戶端程式庫儲存及擷取資料。本文假設您已依設定 Cloud Storage 一文的指示啟用 Cloud Storage 值區及下載用戶端程式庫,同時假設您知道如何建構 App Engine 應用程式。

如需其他程式碼範例,請參閱 Cloud Storage 用戶端程式庫

必要匯入項目

App Engine 與 Cloud Storage 所需檔案中的匯入項目包括:

  • google.golang.org/appengine
  • google.golang.org/appengine/file
  • cloud.google.com/go/storage

如以下程式碼片段所示:

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"

	"cloud.google.com/go/storage"
	"golang.org/x/net/context"
	"google.golang.org/api/iterator"
	"google.golang.org/appengine"
	"google.golang.org/appengine/file"
	"google.golang.org/appengine/log"
)

指定 Cloud Storage 值區

您必須先提供值區名稱,才能執行任何 Cloud Storage 作業。最簡單的方法是使用專案的預設值區,您可以從 App Engine 情境取得,如這段程式碼片段所示:

// Use `dev_appserver.py --default_gcs_bucket_name GCS_BUCKET_NAME`
// when running locally.
bucket, err := file.DefaultBucketName(ctx)
if err != nil {
	log.Errorf(ctx, "failed to get default GCS bucket name: %v", err)
}

寫入 Cloud Storage

如要將檔案寫入至 Cloud Storage:

// createFile creates a file in Google Cloud Storage.
func (d *demo) createFile(fileName string) {
	fmt.Fprintf(d.w, "Creating file /%v/%v\n", d.bucketName, fileName)

	wc := d.bucket.Object(fileName).NewWriter(d.ctx)
	wc.ContentType = "text/plain"
	wc.Metadata = map[string]string{
		"x-goog-meta-foo": "foo",
		"x-goog-meta-bar": "bar",
	}
	d.cleanUp = append(d.cleanUp, fileName)

	if _, err := wc.Write([]byte("abcde\n")); err != nil {
		d.errorf("createFile: unable to write data to bucket %q, file %q: %v", d.bucketName, fileName, err)
		return
	}
	if _, err := wc.Write([]byte(strings.Repeat("f", 1024*4) + "\n")); err != nil {
		d.errorf("createFile: unable to write data to bucket %q, file %q: %v", d.bucketName, fileName, err)
		return
	}
	if err := wc.Close(); err != nil {
		d.errorf("createFile: unable to close bucket %q, file %q: %v", d.bucketName, fileName, err)
		return
	}
}

建立檔案時,範例會指定 Cloud Storage 標頭 (x-goog-meta-foox-goog-meta-bar)。這個選用的程式碼引入使用 Cloud Storage 標頭的概念,您可以套用至:

上方的 x-goog-meta-* 標頭是您可以設定的自訂檔案中繼資料,這些標頭一律會與檔案一起傳回。請注意,自訂標頭及其資料的可用空間僅限在幾 KB 之內,因此請謹慎使用。

程式碼範例不會設定 x-goog-acl,因此公開讀取權限的預設 Cloud Storage ACL 會在寫入值區時套用至物件。

最後,在完成寫入時需要呼叫 Close() 關閉檔案。如果沒有執行此操作,檔案就不會寫入至 Cloud Storage。請注意,呼叫 Close() 後,您就無法附加至檔案。

從 Cloud Storage 讀取

如何從 Cloud Storage 讀取檔案:

// readFile reads the named file in Google Cloud Storage.
func (d *demo) readFile(fileName string) {
	io.WriteString(d.w, "\nAbbreviated file content (first line and last 1K):\n")

	rc, err := d.bucket.Object(fileName).NewReader(d.ctx)
	if err != nil {
		d.errorf("readFile: unable to open file from bucket %q, file %q: %v", d.bucketName, fileName, err)
		return
	}
	defer rc.Close()
	slurp, err := ioutil.ReadAll(rc)
	if err != nil {
		d.errorf("readFile: unable to read data from bucket %q, file %q: %v", d.bucketName, fileName, err)
		return
	}

	fmt.Fprintf(d.w, "%s\n", bytes.SplitN(slurp, []byte("\n"), 2)[0])
	if len(slurp) > 1024 {
		fmt.Fprintf(d.w, "...%s\n", slurp[len(slurp)-1024:])
	} else {
		fmt.Fprintf(d.w, "%s\n", slurp)
	}
}

列出值區內容

以下範例程式碼顯示如何列出值區的內容:

// listBucket lists the contents of a bucket in Google Cloud Storage.
func (d *demo) listBucket() {
	io.WriteString(d.w, "\nListbucket result:\n")

	query := &storage.Query{Prefix: "foo"}
	it := d.bucket.Objects(d.ctx, query)
	for {
		obj, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			d.errorf("listBucket: unable to list bucket %q: %v", d.bucketName, err)
			return
		}
		d.dumpStats(obj)
	}
}

刪除 Cloud Storage 中的檔案

以下程式碼示範如何使用 ObjectHandle.delete() 方法刪除 Cloud Storage 中的檔案。


// deleteFiles deletes all the temporary files from a bucket created by this demo.
func (d *demo) deleteFiles() {
	io.WriteString(d.w, "\nDeleting files...\n")
	for _, v := range d.cleanUp {
		fmt.Fprintf(d.w, "Deleting file %v\n", v)
		if err := d.bucket.Object(v).Delete(d.ctx); err != nil {
			d.errorf("deleteFiles: unable to delete bucket %q, file %q: %v", d.bucketName, v, err)
			return
		}
	}
}

這個範例會清除在寫入 Cloud Storage 一節中寫入至值區的檔案。

後續步驟