オブジェクトを組み合わせる

概要

このページでは、Cloud Storage オブジェクトを 1 つのオブジェクトにまとめる方法について説明します。作成リクエストは 1~32 個のオブジェクトを受け取り、新しい複合オブジェクトを作成します。複合オブジェクトは、リクエストで指定されたソース オブジェクトを連結したものです。

オブジェクトを作成する場合は、次の点に注意してください。

  • ソース オブジェクトは作成処理の影響を受けません。一時的なものである場合は、作成が正常に完了したら削除する必要があります。

必要な権限

コンソール

Google Cloud コンソールでは、オブジェクトの作成はサポートされていません。代わりに Google Cloud CLI を使用してください。

コマンドライン

コマンドライン ユーティリティを使用してこのガイドを完了するには、適切な IAM 権限が必要です。アクセスするバケットが自分で作成していないプロジェクト内に存在する場合は、必要な権限を含むロールをプロジェクト オーナーに付与する必要があります。

特定の操作に必要な権限の一覧については、gcloud storage コマンドの IAM 権限をご覧ください。

関連するロールのリストについては、Cloud Storage のロールをご覧ください。また、特定の制限された権限を持つカスタムロールを作成することもできます。

クライアント ライブラリ

Cloud Storage クライアント ライブラリを使用してこのガイドを完了するには、適切な IAM 権限が必要です。アクセスするバケットが自分で作成していないプロジェクト内に存在する場合は、必要な権限を含むロールをプロジェクト オーナーに付与する必要があります。

特に断りのない限り、クライアント ライブラリのリクエストは JSON API を介して行われ、JSON メソッドの IAM 権限に記載されている権限が必要です。クライアント ライブラリを使用してリクエストを行うときに呼び出される JSON API メソッドを確認するには、元のリクエストをログに記録します。

関連する IAM ロールのリストについては、Cloud Storage のロールをご覧ください。また、特定の制限された権限を持つカスタムロールを作成することもできます。

REST API

JSON API

JSON API を使用してこのガイドを完了するには、適切な IAM 権限が付与されている必要があります。アクセスするバケットが自分で作成していないプロジェクト内に存在する場合は、必要な権限を含むロールをプロジェクト オーナーに付与する必要があります。

特定のアクションに必要な権限の一覧については、JSON メソッドの IAM 権限をご覧ください。

関連するロールのリストについては、Cloud Storage のロールをご覧ください。また、特定の制限された権限を持つカスタムロールを作成することもできます。

複合オブジェクトを作成する

コンソール

Google Cloud コンソールでは、オブジェクトの作成はサポートされていません。代わりに Google Cloud CLI を使用してください。

コマンドライン

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

ここで

  • BUCKET_NAME は、ソース オブジェクトを含むバケットの名前です。
  • SOURCE_OBJECT_1SOURCE_OBJECT_2 は、オブジェクト作成で使用するソース オブジェクトの名前です。
  • COMPOSITE_OBJECT_NAME は、オブジェクト作成の結果に付ける名前です。

クライアント ライブラリ

C++

詳細については、Cloud Storage C++ API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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#

詳細については、Cloud Storage C# API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。


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

詳細については、Cloud Storage Go API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

詳細については、Cloud Storage Java API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

詳細については、Cloud Storage Node.js API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

詳細については、Cloud Storage PHP API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

詳細については、Cloud Storage Python API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

詳細については、Cloud Storage Ruby API のリファレンス ドキュメントをご覧ください。

Cloud Storage に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

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

REST API

JSON API

  1. OAuth 2.0 Playground から認可アクセス トークンを取得します。固有の OAuth 認証情報を使用するように Playground を構成します。手順については、API 認証をご覧ください。
  2. 次の情報が含まれる JSON ファイルを作成します。

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

    ここで

    • SOURCE_OBJECT_1SOURCE_OBJECT_2 は、オブジェクト作成で使用するソース オブジェクトの名前です。
    • COMPOSITE_OBJECT_CONTENT_TYPE は、結果として得られる複合オブジェクトの Content-Type です。
  3. cURL を使用して、POST Object リクエストで JSON API を呼び出します。

    curl -X POST --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer OAUTH2_TOKEN" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/o/COMPOSITE_OBJECT_NAME/compose"

    ここで

    • JSON_FILE_NAME は、前の手順で作成したファイルの名前です。
    • OAUTH2_TOKEN は、ガイドの早い段階で生成したアクセス トークンです。
    • BUCKET_NAME は、ソース オブジェクトを含むバケットの名前です。
    • COMPOSITE_OBJECT_NAME は、オブジェクト作成の結果に付ける名前です。

成功した場合、レスポンスは結果として得られる複合オブジェクトのオブジェクト リソースです。

XML API

  1. OAuth 2.0 Playground から認証アクセス トークンを取得します。固有の OAuth 認証情報を使用するように Playground を構成します。手順については、API 認証をご覧ください。
  2. 次の情報が含まれる XML ファイルを作成します。

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

    ここで

    • SOURCE_OBJECT_1SOURCE_OBJECT_2 は、オブジェクト作成で使用するソース オブジェクトの名前です。
  3. cURL を使用して、PUT Object リクエストと compose クエリ文字列パラメータを含めた XML API を呼び出します。

    curl -X PUT --data-binary @XML_FILE_NAME \
      -H "Authorization: Bearer OAUTH2_TOKEN" \
      -H "Content-Type: COMPOSITE_OBJECT_CONTENT_TYPE" \
      "https://storage.googleapis.com/BUCKET_NAME/COMPOSITE_OBJECT_NAME?compose"

    ここで

    • XML_FILE_NAME は、前の手順で作成したファイルの名前です。
    • OAUTH2_TOKEN は、ガイドの早い段階で生成したアクセス トークンです。
    • COMPOSITE_OBJECT_CONTENT_TYPE は、結果として得られる複合オブジェクトの Content-Type です。
    • BUCKET_NAME は、ソース オブジェクトを含むバケットの名前です。
    • COMPOSITE_OBJECT_NAME は、オブジェクト作成の結果に付ける名前です。

成功した場合は、空のレスポンス本文が返されます。

次のステップ