Compor objetos

Visão geral

Nesta página, mostramos como compor objetos do Cloud Storage em um único objeto. Uma solicitação de composição usa entre 1 e 32 objetos e cria um novo objeto composto. O objeto composto é uma concatenação dos objetos de origem na ordem em que foram especificados na solicitação.

As compor objetos, lembre-se disto:

  • Os objetos de origem não são afetados pelo processo de composição. Se eles forem temporários, será necessário excluí-los depois que a composição for concluída com sucesso.

Funções exigidas

Para receber as permissões necessárias para compor objetos, peça ao administrador para conceder a você o papel de IAM de Usuário do objeto do Storage (roles/storage.objectUser) no bucket. Esse papel predefinido contém as permissões necessárias para compor objetos. Para conferir as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

  • storage.objects.create
  • storage.objects.delete
    • Essa permissão só será necessária se você quiser dar ao objeto que está compondo o mesmo nome de um objeto que já existe no bucket.
  • storage.objects.get
  • storage.objects.list
    • Essa permissão só será necessária se você quiser usar caracteres curinga para compor objetos com um prefixo comum sem precisar listar cada objeto separadamente no comando da CLI do Google Cloud.

Se você quiser definir uma configuração de retenção para o objeto que criar, também precisará da permissão storage.objects.setRetention. Para receber essa permissão, peça ao administrador para conceder a você o papel Administrador de objetos do Storage (roles/storage.objectAdmin), em vez do papel de Usuário do objeto do Storage (roles/storage.objectUser).

Também é possível conseguir essas permissões com outros papéis predefinidos ou personalizados.

Para informações sobre como conceder papéis nos buckets, consulte Usar o IAM com buckets.

Criar um objeto composto

Linha de comando

Use o comando gcloud storage objects compose:

gcloud storage objects compose gs://BUCKET_NAME/SOURCE_OBJECT_1 gs://BUCKET_NAME/SOURCE_OBJECT_2 gs://BUCKET_NAME/COMPOSITE_OBJECT_NAME

Em que:

  • BUCKET_NAME é o nome do bucket que contém os objetos de origem.
  • SOURCE_OBJECT_1 e SOURCE_OBJECT_2 são os nomes dos objetos de origem a serem usados na composição do objeto.
  • COMPOSITE_OBJECT_NAME é o nome que você atribui ao resultado da composição do objeto.

Bibliotecas de cliente

C++

Para mais informações, consulte a documentação de referência da API Cloud Storage C++.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

namespace gcs = ::google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& destination_object_name,
   std::vector<gcs::ComposeSourceObject> const& compose_objects) {
  StatusOr<gcs::ObjectMetadata> composed_object = client.ComposeObject(
      bucket_name, compose_objects, destination_object_name);
  if (!composed_object) throw std::move(composed_object).status();

  std::cout << "Composed new object " << composed_object->name()
            << " in bucket " << composed_object->bucket()
            << "\nFull metadata: " << *composed_object << "\n";
}

C#

Para mais informações, consulte a documentação de referência da API Cloud Storage C#.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.


using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
using System.Collections.Generic;

public class ComposeObjectSample
{
    public void ComposeObject(
        string bucketName = "your-bucket-name",
        string firstObjectName = "your-first-object-name",
        string secondObjectName = "your-second-object-name",
        string targetObjectName = "new-composite-object-name")
    {
        var storage = StorageClient.Create();

        var sourceObjects = new List<ComposeRequest.SourceObjectsData>
        {
            new ComposeRequest.SourceObjectsData { Name = firstObjectName },
            new ComposeRequest.SourceObjectsData { Name = secondObjectName }
        };
        //You could add as many sourceObjects as you want here, up to the max of 32.

        storage.Service.Objects.Compose(new ComposeRequest
        {
            SourceObjects = sourceObjects,
            Destination = new Google.Apis.Storage.v1.Data.Object { ContentType = "text/plain" }
        }, bucketName, targetObjectName).Execute();

        Console.WriteLine($"New composite file {targetObjectName} was created in bucket {bucketName}" +
            $" by combining {firstObjectName} and {secondObjectName}.");
    }
}

Go

Para mais informações, consulte a documentação de referência da API Cloud Storage Go.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// composeFile composes source objects to create a composite object.
func composeFile(w io.Writer, bucket, object1, object2, toObject string) error {
	// bucket := "bucket-name"
	// object1 := "object-name-1"
	// object2 := "object-name-2"
	// toObject := "object-name-3"

	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	src1 := client.Bucket(bucket).Object(object1)
	src2 := client.Bucket(bucket).Object(object2)
	dst := client.Bucket(bucket).Object(toObject)

	// ComposerFrom takes varargs, so you can put as many objects here
	// as you want.
	_, err = dst.ComposerFrom(src1, src2).Run(ctx)
	if err != nil {
		return fmt.Errorf("ComposerFrom: %w", err)
	}
	fmt.Fprintf(w, "New composite object %v was created by combining %v and %v\n", toObject, object1, object2)
	return nil
}

Java

Para mais informações, consulte a documentação de referência da API Cloud Storage Java.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class ComposeObject {
  public static void composeObject(
      String bucketName,
      String firstObjectName,
      String secondObjectName,
      String targetObjectName,
      String projectId) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The ID of the first GCS object to compose
    // String firstObjectName = "your-first-object-name";

    // The ID of the second GCS object to compose
    // String secondObjectName = "your-second-object-name";

    // The ID to give the new composite object
    // String targetObjectName = "new-composite-object-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();

    // Optional: set a generation-match precondition to avoid potential race
    // conditions and data corruptions. The request returns a 412 error if the
    // preconditions are not met.
    Storage.BlobTargetOption precondition;
    if (storage.get(bucketName, targetObjectName) == null) {
      // For a target object that does not yet exist, set the DoesNotExist precondition.
      // This will cause the request to fail if the object is created before the request runs.
      precondition = Storage.BlobTargetOption.doesNotExist();
    } else {
      // If the destination already exists in your bucket, instead set a generation-match
      // precondition. This will cause the request to fail if the existing object's generation
      // changes before the request runs.
      precondition =
          Storage.BlobTargetOption.generationMatch(
              storage.get(bucketName, targetObjectName).getGeneration());
    }

    Storage.ComposeRequest composeRequest =
        Storage.ComposeRequest.newBuilder()
            // addSource takes varargs, so you can put as many objects here as you want, up to the
            // max of 32
            .addSource(firstObjectName, secondObjectName)
            .setTarget(BlobInfo.newBuilder(bucketName, targetObjectName).build())
            .setTargetOptions(precondition)
            .build();

    Blob compositeObject = storage.compose(composeRequest);

    System.out.println(
        "New composite object "
            + compositeObject.getName()
            + " was created by combining "
            + firstObjectName
            + " and "
            + secondObjectName);
  }
}

Node.js

Para mais informações, consulte a documentação de referência da API Cloud Storage Node.js.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of the first GCS file to compose
// const firstFileName = 'your-first-file-name';

// The ID of the second GCS file to compose
// const secondFileName = 'your-second-file-name';

// The ID to give the new composite file
// const destinationFileName = 'new-composite-file-name';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function composeFile() {
  const bucket = storage.bucket(bucketName);
  const sources = [firstFileName, secondFileName];

  // Optional:
  // Set a generation-match precondition to avoid potential race conditions
  // and data corruptions. The request to compose is aborted if the object's
  // generation number does not match your precondition. For a destination
  // object that does not yet exist, set the ifGenerationMatch precondition to 0
  // If the destination object already exists in your bucket, set instead a
  // generation-match precondition using its generation number.
  const combineOptions = {
    ifGenerationMatch: destinationGenerationMatchPrecondition,
  };
  await bucket.combine(sources, destinationFileName, combineOptions);

  console.log(
    `New composite file ${destinationFileName} was created by combining ${firstFileName} and ${secondFileName}`
  );
}

composeFile().catch(console.error);

PHP

Para mais informações, consulte a documentação de referência da API Cloud Storage PHP.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

use Google\Cloud\Storage\StorageClient;

/**
 * Compose two objects into a single target object.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $firstObjectName The name of the first GCS object to compose.
 *        (e.g. 'my-object-1')
 * @param string $secondObjectName The name of the second GCS object to compose.
 *        (e.g. 'my-object-2')
 * @param string $targetObjectName The name of the object to be created.
 *        (e.g. 'composed-my-object-1-my-object-2')
 */
function compose_file(string $bucketName, string $firstObjectName, string $secondObjectName, string $targetObjectName): void
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);

    // In this example, we are composing only two objects, but Cloud Storage supports
    // composition of up to 32 objects.
    $objectsToCompose = [$firstObjectName, $secondObjectName];

    $targetObject = $bucket->compose($objectsToCompose, $targetObjectName, [
        'destination' => [
            'contentType' => 'application/octet-stream'
        ]
    ]);

    if ($targetObject->exists()) {
        printf(
            'New composite object %s was created by combining %s and %s',
            $targetObject->name(),
            $firstObjectName,
            $secondObjectName
        );
    }
}

Python

Para mais informações, consulte a documentação de referência da API Cloud Storage Python.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import storage


def compose_file(bucket_name, first_blob_name, second_blob_name, destination_blob_name):
    """Concatenate source blobs into destination blob."""
    # bucket_name = "your-bucket-name"
    # first_blob_name = "first-object-name"
    # second_blob_name = "second-blob-name"
    # destination_blob_name = "destination-object-name"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    destination = bucket.blob(destination_blob_name)
    destination.content_type = "text/plain"

    # Note sources is a list of Blob instances, up to the max of 32 instances per request
    sources = [bucket.blob(first_blob_name), bucket.blob(second_blob_name)]

    # Optional: set a generation-match precondition to avoid potential race conditions
    # and data corruptions. The request to compose is aborted if the object's
    # generation number does not match your precondition. For a destination
    # object that does not yet exist, set the if_generation_match precondition to 0.
    # If the destination object already exists in your bucket, set instead a
    # generation-match precondition using its generation number.
    # There is also an `if_source_generation_match` parameter, which is not used in this example.
    destination_generation_match_precondition = 0

    destination.compose(sources, if_generation_match=destination_generation_match_precondition)

    print(
        "New composite object {} in the bucket {} was created by combining {} and {}".format(
            destination_blob_name, bucket_name, first_blob_name, second_blob_name
        )
    )
    return destination

Ruby

Para mais informações, consulte a documentação de referência da API Cloud Storage Ruby.

Para autenticar no Cloud Storage, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

def compose_file bucket_name:, first_file_name:, second_file_name:, destination_file_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The ID of the first GCS object to compose
  # first_file_name = "your-first-file-name"

  # The ID of the second GCS object to compose
  # second_file_name = "your-second-file-name"

  # The ID to give the new composite object
  # destination_file_name = "new-composite-file-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket = storage.bucket bucket_name, skip_lookup: true

  destination = bucket.compose [first_file_name, second_file_name], destination_file_name do |f|
    f.content_type = "text/plain"
  end

  puts "Composed new file #{destination.name} in the bucket #{bucket_name} " \
       "by combining #{first_file_name} and #{second_file_name}"
end

APIs REST

API JSON

  1. Ter a gcloud CLI instalada e inicializadapara gerar um token de acesso para o cabeçalho Authorization.

    Como alternativa, é possível criar um token de acesso usando o OAuth 2.0 Playground e incluí-lo no cabeçalho Authorization.

  2. Crie um arquivo JSON com as informações a seguir:

    {
      "sourceObjects": [
        {
          "name": "SOURCE_OBJECT_1"
        },
        {
          "name": "SOURCE_OBJECT_2"
        }
      ],
      "destination": {
        "contentType": "COMPOSITE_OBJECT_CONTENT_TYPE"
      }
    }

    Em que:

    • SOURCE_OBJECT_1 e SOURCE_OBJECT_2 são os nomes dos objetos de origem a serem usados na composição do objeto.
    • COMPOSITE_OBJECT_CONTENT_TYPE é o tipo de conteúdo do objeto composto resultante.
  3. Use cURL para chamar a API JSON com uma solicitação de POST Objeto:

    curl -X POST --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/COMPOSITE_OBJECT_NAME/compose"

    Em que:

    • JSON_FILE_NAME é o nome do arquivo criado na etapa anterior.
    • BUCKET_NAME é o nome do bucket que contém os objetos de origem.
    • COMPOSITE_OBJECT_NAME é o nome que você atribui ao resultado da composição do objeto.

Se bem-sucedida, a resposta será um recurso de objeto para o objeto composto resultante.

API XML

  1. Ter a gcloud CLI instalada e inicializadapara gerar um token de acesso para o cabeçalho Authorization.

    Como alternativa, é possível criar um token de acesso usando o OAuth 2.0 Playground e incluí-lo no cabeçalho Authorization.

  2. Crie um arquivo .xml com as informações a seguir:

      <ComposeRequest>
        <Component>
          <Name>SOURCE_OBJECT_1</Name>
        </Component>
        <Component>
          <Name>SOURCE_OBJECT_2</Name>
        </Component>
      </ComposeRequest>

    Em que:

    • SOURCE_OBJECT_1 e SOURCE_OBJECT_2 são os nomes dos objetos de origem a serem usados na composição do objeto.
  3. Use cURL (em inglês) para chamar a API XML com uma solicitação de objeto PUT e um parâmetro de string de consulta compose:

    curl -X PUT --data-binary @XML_FILE_NAME \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: COMPOSITE_OBJECT_CONTENT_TYPE" \
      "https://storage.googleapis.com/BUCKET_NAME/COMPOSITE_OBJECT_NAME?compose"

    Em que:

    • XML_FILE_NAME é o nome do arquivo criado na etapa anterior.
    • COMPOSITE_OBJECT_CONTENT_TYPE é o tipo de conteúdo do objeto composto resultante.
    • BUCKET_NAME é o nome do bucket que contém os objetos de origem.
    • COMPOSITE_OBJECT_NAME é o nome que você atribui ao resultado da composição do objeto.

Se o processo for bem-sucedido, um corpo vazio de resposta será retornado.

A seguir