Leer y escribir en Cloud Storage

En este documento se describe cómo almacenar y obtener datos mediante la biblioteca de cliente de Cloud Storage. Se da por hecho que has completado las tareas descritas en Configurar Cloud Storage para activar un segmento de Cloud Storage y descargar las bibliotecas de cliente. También se presupone que sabes cómo crear una aplicación de App Engine.

Para ver más ejemplos de código, consulta las bibliotecas de cliente de Cloud Storage .

Importaciones necesarias

Las importaciones del archivo necesarias 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"
)

Especificar el segmento de Cloud Storage

Para poder ejecutar cualquier operación de Cloud Storage, debes proporcionar el nombre del segmento. La forma más sencilla de hacerlo es usar el bucket predeterminado de tu 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)
}

Escribir en Cloud Storage

Para escribir un archivo en Cloud Storage, sigue estos pasos:

// 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, el ejemplo especifica los encabezados de Cloud Storage (x-goog-meta-foo y x-goog-meta-bar). Este código opcional introduce el concepto de usar encabezados de Cloud Storage, que puedes aplicar a lo siguiente:

  • Afectar al comportamiento de las solicitudes
  • Especifica el acceso al archivo en el segmento, que es diferente de los valores predeterminados (consulta x-goog-acl).
  • Escribe metadatos de archivo.

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

Como el ejemplo de código no define x-goog-acl, se aplica al objeto la LCA de Cloud Storage predeterminada de lectura pública cuando se escribe en el contenedor.

Por último, observa la llamada a 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 podrás añadir contenido al archivo.

Leer desde Cloud Storage

Para leer un archivo de Cloud Storage, sigue estos pasos:

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

Mostrar el contenido de un segmento

En este código de ejemplo se muestra cómo enumerar el contenido del segmento:

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

Eliminar archivos de Cloud Storage

En el siguiente código se muestra cómo eliminar 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
		}
	}
}

En este ejemplo, se eliminan los archivos que se escribieron en el segmento de la sección Escribir en Cloud Storage.

Siguientes pasos