All Products
Search
Document Center

Object Storage Service:Copy objects

Last Updated:Nov 04, 2024

This topic describes how to copy an object within a bucket or across buckets in the same region.

Usage notes

  • In this topic, the public endpoint of the China (Hangzhou) region is used. If you want to access OSS from other Alibaba Cloud services in the same region as OSS, use an internal endpoint. For more information about OSS regions and endpoints, see Regions, endpoints and open ports.

  • In this topic, access credentials are obtained from environment variables. For more information about how to configure access credentials, see Configure access credentials.

  • In this topic, an OSSClient instance is created by using an OSS endpoint. If you want to create an OSSClient instance by using custom domain names or Security Token Service (STS), see Initialization.

  • To copy an object, you must have read permissions on the source object and read and write permissions on the destination bucket.

  • Make sure that no retention policies are configured for the source bucket and the destination bucket. Otherwise, the error message The object you specified is immutable. is returned.

  • The source bucket and destination bucket must be in the same region. For example, objects cannot be copied from a bucket located in the China (Hangzhou) region to another bucket located in the China (Qingdao) region.

Sample code

Copy a small object

You can call CopyObject to copy an object within a bucket or across buckets in the same region. We recommend that you call CopyObject to copy an object that is smaller than 1 GB in size.

Copy objects within the same bucket

package main

import (
	"log"
	"time"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// Create an OSSClient instance. 
	// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint. 
	// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. Specify the actual region.
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// Specify the version of the signature algorithm.
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// Specify the name of the bucket. Example: examplebucket. 
	bucketName := "examplebucket"
	// Specify the full path of the source object. Example: srcdir/srcobject.jpg. 
	objectName := "srcdir/srcobject.jpg"
	// Specify the full path of the destination object. Example: destdir/destobject.jpg.
	destObjectName := "destdir/destobject.jpg"

	// Obtain the bucket information. 
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
	}

	// Specify the metadata of the destination object. 
	expires := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
	tag1 := oss.Tag{
		Key:   "a",
		Value: "1",
	}

	taggingInfo := oss.Tagging{
		Tags: []oss.Tag{tag1},
	}

	options := []oss.Option{
		oss.MetadataDirective(oss.MetaReplace),
		oss.Expires(expires),
		oss.SetTagging(taggingInfo),
		// Copy the tags of the source object to the destination object. 
		// oss.TaggingDirective(oss.TaggingCopy),
		// Set the access control list (ACL) of the destination object to private when OSS creates the destination object.  
		// oss.ObjectACL(oss.ACLPrivate),
		// Specify the customer master key (CMK) that is managed by Key Management Service (KMS). This parameter takes effect only when x-oss-server-side-encryption is set to KMS. 
		// oss.ServerSideEncryptionKeyID("9468da86-3509-4f8d-a61e-6eab1eac****"),
		// Specify the server-side encryption algorithm that is used to encrypt the destination object when OSS creates the object. 
		// oss.ServerSideEncryption("AES256"),
		// Copy the metadata of the source object to the destination object. 
		// oss.MetadataDirective(oss.MetaCopy),
		// Specify whether the CopyObject operation overwrites an object that has the same name as the source bucket. In this example, this parameter is set to true. The value true indicates that the operation does not overwrite an object that has the same name as the source bucket. 
		// oss.ForbidOverWrite(true),
		// If the ETag value that you specify in the request is the same as the ETag value of the source object, OSS copies the object and returns 200 OK. 
		// oss.CopySourceIfMatch("5B3C1A2E053D763E1B002CC607C5****"),
		// If the ETag value that you specify in the request is different from the ETag value of the source object, OSS copies the object and returns 200 OK. 
		// oss.CopySourceIfNoneMatch("5B3C1A2E053D763E1B002CC607C5****"),
		// If the time specified in the request is earlier than the actual time when the object is modified, OSS copies the object and returns 200 OK. 
		// oss.CopySourceIfModifiedSince(time.Date(2021, time.December, 9, 7, 1, 56, 0, time.UTC)),
		// If the time specified in the request is the same as or later than the modification time of the object, OSS copies the object and returns 200 OK. 
		// oss.CopySourceIfUnmodifiedSince(time.Date(2021, time.December, 9, 7, 1, 56, 0, time.UTC)),
		// Specify the storage class of the destination object. In this example, the storage class is set to Standard. 
		// oss.StorageClass("Standard"),
	}

	// Overwrite the metadata of the source object by using the metadata that you specify in the request. 
	_, err = bucket.CopyObject(objectName, destObjectName, options...)
	if err != nil {
		log.Fatalf("Failed to copy object from '%s' to '%s': %v", objectName, destObjectName, err)
	}

	log.Printf("Successfully copied object from '%s' to '%s'", objectName, destObjectName)
}

Copy an object across buckets in the same region

package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// Create an OSSClient instance. 
	// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint. 
	// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. Specify the actual region.
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// Specify the version of the signature algorithm.
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// Specify the name of the source bucket. Example: srcbucket. 
	srcBucketName := "srcbucket"
	// Specify the full path of the source object. Example: srcobject.jpg. 
	srcObjectName := "srcobject.jpg"
	// Specify the full path of the destination object. Example: destobject.jpg. 
	dstObjectName := "destobject.jpg"
	// Specify the name of the destination bucket. Example: destbucket. 
	destBucketName := "destbucket"

	// Create the destination bucket.
	bucket, err := client.Bucket(destBucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket '%s': %v", destBucketName, err)
	}

	// Copy the srcobject.jpg object from srcbucket to the destobject.jpg object in destbucket. 
	_, err = bucket.CopyObjectFrom(srcBucketName, srcObjectName, dstObjectName)
	if err != nil {
		log.Fatalf("Failed to copy object from '%s/%s' to '%s/%s': %v", srcBucketName, srcObjectName, destBucketName, dstObjectName, err)
	}

	log.Printf("Successfully copied object from '%s/%s' to '%s/%s'", srcBucketName, srcObjectName, destBucketName, dstObjectName)
}

Copy a large object

The following code provides an example on how to copy a large object:

package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Failed to create credentials provider: %v", err)
	}

	// Create an OSSClient instance. 
	// Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint. 
	// Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. Specify the actual region.
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// Specify the version of the signature algorithm.
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		log.Fatalf("Failed to create OSS client: %v", err)
	}

	// Specify the name of the bucket. Example: examplebucket. 
	bucketName := "examplebucket"

	// Obtain the bucket information. 
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		log.Fatalf("Failed to get bucket '%s': %v", bucketName, err)
	}

	// Specify the full path of the source object. Example: srcobject.txt. 
	objectSrc := "srcobject.txt"
	// Specify the full path of the destination object. Example: destobject.txt. 
	objectDest := "destobject.txt"
	// Specify the full path of the local file. 
	fileName := "D:\\localpath\\examplefile.txt"

	// Splits the object into multiple chunks.
	chunks, err := oss.SplitFileByPartNum(fileName, 3)
	if err != nil {
		log.Fatalf("Failed to split file: %v", err)
	}

	// Upload the file to OSS.
	err = bucket.PutObjectFromFile(objectSrc, fileName)
	if err != nil {
		log.Fatalf("Failed to upload object '%s' from file '%s': %v", objectSrc, fileName, err)
	}

	// Initiate Multipart Upload.
	imur, err := bucket.InitiateMultipartUpload(objectDest)
	if err != nil {
		log.Fatalf("Failed to initiate multipart upload for '%s': %v", objectDest, err)
	}

	var parts []oss.UploadPart
	for _, chunk := range chunks {
		// Specify options for Multipart Upload.
		options := []oss.Option{}

		// Copy the uploaded parts.
		part, err := bucket.UploadPartCopy(imur, bucketName, objectSrc, chunk.Offset, chunk.Size, chunk.Number, options...)
		if err != nil {
			log.Fatalf("Failed to upload part %d of '%s': %v", chunk.Number, objectSrc, err)
		}
		parts = append(parts, part)
	}

	// Complete Multipart Upload.
	cmur, err := bucket.CompleteMultipartUpload(imur, parts)
	if err != nil {
		log.Fatalf("Failed to complete multipart upload for '%s': %v", objectDest, err)
	}

	log.Printf("Multipart upload completed successfully for '%s'. cmur: %v", objectDest, cmur)
}

References

  • For the complete sample code that is used to copy an object, visit GitHub.

  • For more information about the API operation that you can call to copy a small object, see CopyObject.

  • For more information about the API operation that you can call to copy a large object, see UploadPartCopy.