Lire et écrire sur Cloud Storage

Ce document explique comment stocker et récupérer des données à l'aide de la bibliothèque cliente Cloud Storage. Nous supposons ici que vous avez réalisé les tâches décrites dans la documentation Configuration de Google Cloud Storage pour activer un bucket Cloud Storage et télécharger les bibliothèques clientes. Nous supposons également que vous savez comment créer une application App Engine.

Pour obtenir d'autres exemples de code, consultez la page Bibliothèques clientes Cloud Storage.

Importations requises

Voici les importations requises dans le fichier pour App Engine et Cloud Storage :

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

L'extrait suivant illustre ceci :

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"
)

Spécifier le bucket Cloud Storage

Avant de pouvoir exécuter des opérations Cloud Storage, vous devez fournir le nom du bucket. Pour ce faire, le plus simple consiste à utiliser le bucket par défaut de votre projet. Il peut être obtenu à partir du contexte App Engine, comme décrit dans cet extrait :

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

Écrire dans Cloud Storage

Pour écrire un fichier dans 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
	}
}

Une fois le fichier créé, l'exemple spécifie des en-têtes Cloud Storage (x-goog-meta-foo et x-goog-meta-bar). Ce code facultatif introduit la notion de l'utilisation d'en-têtes Cloud Storage, qui vous permettent d'effectuer les actions suivantes :

  • Affecter le comportement de la requête
  • Spécifier un accès au fichier différent des valeurs par défaut dans le bucket (voir x-goog-acl)
  • Écrire des métadonnées de fichier

Les en-têtes x-goog-meta-* ci-dessus sont des métadonnées de fichier personnalisées que vous pouvez définir. Ces en-têtes sont toujours renvoyés avec le fichier. Notez que l'espace disponible pour les en-têtes personnalisés et leurs données est limité à quelques kilo-octets. Utilisez-les donc judicieusement :

Comme l'exemple de code ne définit pas x-goog-acl, la LCA Cloud Storage par défaut pour la lecture publique est appliquée à l'objet lorsqu'il est écrit dans le bucket.

Enfin, vous pouvez constater que l'appel Close() ferme le fichier une fois l'écriture terminée. Si cet appel n'est pas émis, le fichier n'est pas écrit dans Cloud Storage. Sachez qu'après avoir appelé Close(), vous ne pouvez plus rien ajouter au fichier.

Lire à partir de Cloud Storage

Pour lire un fichier à partir de 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)
	}
}

Répertorier le contenu du bucket

L'exemple de code suivant décrit comment répertorier le contenu du bucket :

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

Supprimer des fichiers de Cloud Storage

Le code ci-dessous indique comment supprimer un fichier de Cloud Storage à l'aide de la méthode ObjectHandle.delete().


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

Cet exemple nettoie les fichiers qui ont été écrits dans le bucket, tel que décrit dans la section Écrire des données dans Cloud Storage.

Étapes suivantes