读取和写入 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-* 标头是您可以设置的自定义文件元数据;这些标头始终随文件一起返回。请注意,可供自定义标头及其数据使用的空间上限为几千字节,请谨慎使用。

由于上述代码示例未设置 x-goog-acl,因此默认情况下,系统对写入存储桶的对象应用的 Cloud Storage ACL 为 public read

最后,请注意在完成写入后,应调用 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 中写入数据部分中写入存储分区的文件。

后续步骤