Como ler e gravar no Cloud Storage

Neste documento, você verá a descrição de como armazenar e recuperar dados usando a biblioteca de cliente do App Engine para Cloud Storage. O ideal é que você já tenha concluído as tarefas descritas na seção Como configurar o Google Cloud Storage para ativar um bucket do Cloud Storage e fazer o download das bibliotecas de cliente. Também é necessário que você saiba criar um aplicativo do App Engine, conforme descrito em Guia de início rápido para o Go 1.11 no ambiente padrão do App Engine.

Importações obrigatórias

As importações necessárias no arquivo para o App Engine e para o Cloud Storage são:

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

como mostrado no seguinte 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"
)

Como especificar o bucket do Cloud Storage

Antes de executar qualquer operação do Cloud Storage, é necessário fornecer o nome do bucket. A maneira mais fácil de fazer isso é usar o bucket padrão para o projeto, que pode ser obtido no contexto do App Engine, conforme mostrado neste snippet:

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

Como gravar no Cloud Storage

Para gravar um arquivo no 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
	}
}

Quando o arquivo é criado, a amostra especifica os cabeçalhos do Cloud Storage (x-goog-meta-foo e x-goog-meta-bar). Esse código opcional apresenta a noção de uso de cabeçalhos do Cloud Storage, que você pode aplicar para:

  • afetar o comportamento da solicitação;
  • especificar o acesso ao arquivo no bucket diferente dos padrões (veja x-goog-acl);
  • gravar metadados de arquivo.

Os cabeçalhos x-goog-meta-* mostrados acima são metadados de arquivos personalizados configuráveis e sempre são retornados com o arquivo. Observe que o espaço disponível para cabeçalhos personalizados e os dados deles é limitado a alguns kilobytes. Por isso, use-os com cuidado.

Como o código de amostra não define x-goog-acl, a ACL padrão do Cloud Storage de leitura pública é aplicada ao objeto quando ele é gravado no bucket.

Por fim, observe a chamada para usar Close() no arquivo depois de concluir a gravação. Se não usá-lo, o arquivo não será gravado no Cloud Storage. Depois de chamar Close(), não será possível anexar ao arquivo.

Como fazer a leitura do Cloud Storage

Para ler um arquivo do 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)
	}
}

Como listar conteúdo do bucket

Com este código de amostra, é possível listar o conteúdo do 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)
	}
}

Como excluir arquivos no Cloud Storage

O código abaixo demonstra como excluir um arquivo do Cloud Storage usando o 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 exemplo limpa os arquivos que foram gravados no bucket na seção Como gravar no Cloud Storage.

A seguir