In Cloud Storage lesen und schreiben

In diesem Dokument wird beschrieben, wie Daten mithilfe der Cloud Storage-Clientbibliothek gespeichert und abgerufen werden. Es wird davon ausgegangen, dass Sie die unter Cloud Storage einrichten beschriebenen Aufgaben durchgeführt und somit einen Cloud Storage-Bucket aktiviert sowie die Clientbibliotheken heruntergeladen haben. Außerdem sollten Sie eine App Engine-Anwendung erstellen können.

Weitere Codebeispiele finden Sie unter Cloud Storage-Clientbibliotheken.

Erforderliche Importe

Für App Engine und Cloud Storage sind folgende Importe in der Datei erforderlich:

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

Siehe folgender Snippet:

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-Bucket angeben

Bevor Sie einen Cloud Storage-Vorgang ausführen können, müssen Sie den Bucket-Namen angeben. Am einfachsten ist es, wenn Sie dafür den Standard-Bucket Ihres Projekts verwenden. Dieser kann wie im folgenden Snippet aus dem App Engine-Kontext abgerufen werden:

// 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)
}

Schreibvorgänge in Cloud Storage

So schreiben Sie eine Datei in 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
	}
}

Beim Erstellen der Datei werden im Beispiel Cloud Storage-Header festgelegt (x-goog-meta-foo und x-goog-meta-bar). Dieser optionale Code zeigt die Verwendung von Cloud Storage-Headern, die Sie nutzen können, um

  • das Verhalten von Anfragen zu beeinflussen,
  • den Zugriff auf die Datei im Bucket anzugeben, der sich von den Standardeinstellungen unterscheidet (siehe x-goog-acl), und
  • Dateimetadaten zu schreiben.

Die oben gezeigten x-goog-meta-*-Header sind benutzerdefinierte Dateimetadaten, die Sie festlegen können. Diese Header werden immer mit der Datei zurückgegeben. Der verfügbare Speicherplatz für benutzerdefinierte Header und ihre Daten ist auf wenige Kilobyte beschränkt. Sie sollten sie also mit Bedacht einsetzen.

Da x-goog-acl im Codebeispiel nicht festgelegt wird, wird die standardmäßige Cloud Storage-ACL des öffentlichen Lesezugriffs auf das Objekt angewendet, wenn es in den Bucket geschrieben wird.

Achten Sie außerdem auf den Aufruf von Close() für die Datei, nachdem der Schreibvorgang abgeschlossen ist. Ohne diesen Aufruf wird die Datei nicht in Cloud Storage geschrieben. Nach dem Aufrufen von Close() ist das Anhängen an die Datei nicht möglich.

Lesevorgänge in Cloud Storage

So lesen Sie eine Datei aus 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)
	}
}

Bucket-Inhalt auflisten

Dieser Beispielcode zeigt, wie Sie die Inhalte des Buckets auflisten:

// 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)
	}
}

Dateien in Cloud Storage löschen

Anhand des folgenden Codes wird veranschaulicht, wie Sie mit der Methode ObjectHandle.delete() eine Datei aus Cloud Storage löschen können.


// 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
		}
	}
}

In diesem Beispiel werden die Dateien bereinigt, die im Abschnitt Schreibvorgänge in Cloud Storage in den Bucket geschrieben wurden.

Nächste Schritte