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

Usage notes

  • To copy an object, you must have read permissions on the source object and read and write permissions on the destination bucket.
  • The source bucket and the destination bucket must have no retention policies configured. Otherwise, the error message The object you specified is immutable. is returned.
  • The source bucket and the destination bucket must be in the same region. For example, objects in a bucket located in the China (Hangzhou) region cannot be copied to another bucket located in the China (Qingdao) region.

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 only objects that are smaller than 1 GB in size.

  • Copy an object within a bucket

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

    package main
    
    import (
        "fmt"
        "github.com/aliyun/aliyun-oss-go-sdk/oss"
        "os"
        "time"
    )
    
    func main() {
        // Create an OSSClient instance. 
        // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify the endpoint based on your business requirements. 
        // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access Object Storage Service (OSS) because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine operations and maintenance. To create a RAM user, log on to the RAM console. 
        client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        // 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. 
        bucket, err := client.Bucket(bucketName)
        if err != nil {
            fmt.Println("Error:", err)
    
            os.Exit(-1)
        }
    
        // Specify metadata for 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),
            // Specify that the tags of the source object are copied 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 destination object. 
            // oss.ServerSideEncryption("AES256"),
            // Specify that the metadata of the source object is copied to the destination object. 
            //oss.MetadataDirective(oss.MetaCopy),
            // Specify whether the CopyObject operation overwrites the object with the same name. In this example, this parameter is set to true, which indicates that the object with the same name cannot be overwritten. 
            // oss.ForbidOverWrite(true),
            // If the ETag value of the source object is the same as the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
            //oss.CopySourceIfMatch("5B3C1A2E053D763E1B002CC607C5****"),
            // If the ETag value of the source object is different from the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
            //oss.CopySourceIfNoneMatch("5B3C1A2E053D763E1B002CC607C5****"),
            // If the time that is specified in the request is earlier than the modified time of the object, OSS copies the object and returns 200 OK. 
            //oss.CopySourceIfModifiedSince(2021-12-09T07:01:56.000Z),
            // If the time that is specified in the request is the same as or later than the modified time of the object, OSS copies the object and returns 200 OK. 
            //oss.CopySourceIfUnmodifiedSince(2021-12-09T07:01:56.000Z),
            // Specify the storage class of the destination object. In this example, this parameter is set to Standard. 
            //oss.StorageClass("Standard"),
            }
    
        // Specify that the metadata of the source object is overwritten by the metadata that is specified in the request. 
        _, err = bucket.CopyObject(objectName, destObjectName, options...)
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
    }
  • Copy an object across buckets in the same region

    The following code provides an example on how to copy an object across buckets in the same region:

    package main
    
    import (
      "fmt"
      "os"
      "github.com/aliyun/aliyun-oss-go-sdk/oss"
    )
    
    func main() {
      // Create an OSSClient instance. 
      // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify the endpoint based on your business requirements. 
      // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine operations and maintenance. To create a RAM user, log on to the RAM console. 
      client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
      if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
      }
    
      // 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"
    
      // Obtain the bucket. 
      bucket, err := client.Bucket(destBucketName)
      if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
      }
    
      // Copy an object named srcobject.jpg from the srcbucket bucket to an object named destobject.jpg in the destbucket bucket. 
      _, err = bucket.CopyObjectFrom(srcBucketName, srcObjectName, dstObjectName)
      if err != nil {
        fmt.Println("CopyObjectFrom Error:", err)
        os.Exit(-1)
      }
    }

Copy a large object

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

package main

import (
    "fmt"
    "os"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    // Create an OSSClient instance. 
    // Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify the endpoint based on your business requirements. 
    // Security risks may arise if you use the AccessKey pair of an Alibaba Cloud account to access OSS because the account has permissions on all API operations. We recommend that you use a RAM user to call API operations or perform routine operations and maintenance. To create a RAM user, log on to the RAM console. 
    client, err := oss.New("yourEndpoint", "yourAccessKeyId", "yourAccessKeySecret")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // Specify the name of the bucket. Example: examplebucket. 
    bucketName := "examplebucket"

    // Obtain the bucket. 
    bucket, err := client.Bucket(bucketName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 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.
    var fileName = "D:\\localpath\\examplefile.txt"

    chunks, err := oss.SplitFileByPartNum(fileName, 3)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }


    err = bucket.PutObjectFromFile(objectSrc, fileName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    imur, err := bucket.InitiateMultipartUpload(objectDest)

    var parts []oss.UploadPart
    for _, chunk := range chunks {
        // Specify that the metadata of the source object is overwritten by the metadata that is specified in the request. 
        options := []oss.Option{
            // Specify the range of data that you want to copy. For example, if you specify 0 to 1023 as the range of data that you want to copy, the first 1024 bytes of the source object are copied. 
            // oss.CopySourceRange(0,1023),
            // If the ETag value of the source object is the same as the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
            // oss.CopySourceIfMatch("5B3C1A2E053D763E1B002CC607C5****"),
            // If the ETag value of the source object is different from the ETag value that is specified in the request, OSS copies the object and returns 200 OK. 
            // oss.CopySourceIfNoneMatch("5B3C1A2E053D763E1B002CC607C5****"),
            // If the time that is specified in the request is the same as or later than the modified time of the object, OSS copies the object and returns 200 OK. 
            // oss.CopySourceIfModifiedSince(2021-12-09T07:01:56.000Z),
            // If the time specified in the request is earlier than the modified time of the object, OSS copies the object and returns 200 OK. 
            // oss.CopySourceIfUnmodifiedSince(2021-12-09T07:01:56.000Z),
        }

        part, err := bucket.UploadPartCopy(imur, bucketName, objectSrc, chunk.Offset, chunk.Size, chunk.Number ,options...)
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        parts = append(parts, part)
    }

    cmur, err := bucket.CompleteMultipartUpload(imur, parts)

    fmt.Println("cmur:", cmur)

    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

References

  • For more information about 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.