Leer y escribir en Cloud Storage

En este documento, se describe cómo almacenar y recuperar datos mediante la biblioteca cliente de Cloud Storage. Se supone que realizaste las tareas descritas en Configura Cloud Storage para activar un bucket de Cloud Storage y descargar las bibliotecas cliente. También se supone que sabes cómo compilar una aplicación de App Engine.

Para obtener muestras de código adicionales, consulta Bibliotecas cliente de Cloud Storage

Importaciones requeridas

Las importaciones en el archivo que se requieren para App Engine y Cloud Storage son las siguientes:

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

como se muestra en el siguiente fragmento:

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

Especifica el bucket de Cloud Storage

Antes de que puedas ejecutar cualquier operación de Cloud Storage, debes proporcionar el nombre del bucket. La manera más sencilla de hacerlo es usar el bucket predeterminado para el proyecto, que se puede obtener del contexto de App Engine, como se muestra en este fragmento:

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

Escribe en Cloud Storage

Para escribir un archivo en Cloud Storage, usa lo siguiente:

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

Cuando se crea el archivo, la muestra especifica los encabezados de Cloud Storage (x-goog-meta-foo y x-goog-meta-bar). Este código opcional presenta la idea de usar encabezados de Cloud Storage, que puedes aplicar para lo siguiente:

  • Afectar el comportamiento de las solicitudes
  • Especificar el acceso al archivo en el depósito cuando quieras usar valores distintos de los predeterminados (consulta x-goog-acl)
  • Escribir los metadatos de archivos

Los encabezados x-goog-meta-* anteriores son metadatos de archivos personalizados que puedes configurar. Estos encabezados siempre se muestran con el archivo. Ten en cuenta que el espacio disponible para los encabezados personalizados y sus datos se limita a unos pocos kilobytes, así que úsalos con cuidado.

Debido a que la muestra de código no configura x-goog-acl, la LCA de lectura pública predeterminada de Cloud Storage se aplica al objeto cuando se lo escribe en el bucket.

Por último, observa la llamada para Close() el archivo después de terminar la escritura. Si no lo haces, el archivo no se escribirá en Cloud Storage. Ten en cuenta que después de llamar a Close(), no puedes adjuntar el archivo.

Lee en Cloud Storage

Para leer un archivo desde 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)
	}
}

Enumera el contenido del bucket

Esta muestra de código indica cómo enumerar el contenido del 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)
	}
}

Borra archivos en Cloud Storage

En el siguiente código, se muestra cómo borrar un archivo de Cloud Storage mediante el método 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
		}
	}
}

Este ejemplo limpia los archivos que se escribieron en el depósito en la sección Cómo escribir en Cloud Storage.

¿Qué sigue?