Como ler e gravar no Cloud Storage

Neste documento, descrevemos como armazenar e recuperar dados usando a biblioteca de cliente do 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.

Para ver outras amostras de código, consulte Bibliotecas de cliente do Cloud Storage

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