The Copier module in OSS SDK for Go V2 copies objects between buckets — or within the same bucket — without requiring you to choose between CopyObject and UploadPartCopy. The Copier selects the appropriate underlying operation automatically based on object size.
How it works
OSS provides two copy operations, each suited to a different size range:
| Operation | When it's used | Limitation |
|---|---|---|
CopyObject | Objects smaller than 5 GiB | Does not support multipart |
UploadPartCopy | Objects 5 GiB or larger | Does not support x-oss-metadata-directive or x-oss-tagging-directive |
The Copier wraps both operations and applies them transparently:
Objects smaller than the
MultipartCopyThreshold(default: 200 MiB) are copied usingCopyObject.Objects at or above the threshold are copied using
UploadPartCopyin parallel parts.
Prerequisites
Before you begin, ensure that you have:
Read permission on the source object
Read and write permission on the destination bucket
Source and destination buckets in the same region (cross-region copy is not supported)
No retention policies configured on either bucket (if a retention policy exists, OSS returns:
The object you specified is immutable.)
Copy objects
Create a Copier
// Create a Copier with default options.
c := client.NewCopier()
// Create a Copier with custom options.
c := client.NewCopier(func(o *oss.CopierOptions) {
o.PartSize = 128 * 1024 * 1024 // 128 MiB per part
o.ParallelNum = 5 // 5 concurrent parts
o.MultipartCopyThreshold = 500 * 1024 * 1024 // switch to multipart above 500 MiB
})Copy an object
The following example copies an object from a source bucket to a destination bucket, sets the storage class to Standard, and replaces the source metadata and tags with new values.
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
srcBucketName string
srcObjectName string
destBucketName string
destObjectName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region where the bucket is located.")
flag.StringVar(&srcBucketName, "src-bucket", "", "The name of the source bucket.")
flag.StringVar(&srcObjectName, "src-object", "", "The name of the source object.")
flag.StringVar(&destBucketName, "dest-bucket", "", "The name of the destination bucket.")
flag.StringVar(&destObjectName, "dest-object", "", "The name of the destination object.")
}
func main() {
flag.Parse()
if len(srcBucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// If no destination bucket is specified, copy within the source bucket.
if len(destBucketName) == 0 {
destBucketName = srcBucketName
}
if len(srcObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source object name required")
}
if len(destObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, destination object name required")
}
// Load credentials from environment variables.
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
// Create a Copier.
c := client.NewCopier()
request := &oss.CopyObjectRequest{
Bucket: oss.Ptr(destBucketName),
Key: oss.Ptr(destObjectName),
SourceBucket: oss.Ptr(srcBucketName),
SourceKey: oss.Ptr(srcObjectName),
StorageClass: oss.StorageClassStandard, // Set the destination storage class to Standard.
MetadataDirective: oss.Ptr("Replace"), // Use new metadata instead of copying from the source.
TaggingDirective: oss.Ptr("Replace"), // Use new tags instead of copying from the source.
}
result, err := c.Copy(context.TODO(), request)
if err != nil {
log.Fatalf("failed to copy object: %v", err)
}
log.Printf("copy result: %#v\n", result)
}Access credentials are loaded from theOSS_ACCESS_KEY_IDandOSS_ACCESS_KEY_SECRETenvironment variables. For configuration details, see Configure access credentials.
API reference
NewCopier
func (c *Client) NewCopier(optFns ...func(*CopierOptions)) *CopierCopy
func (c *Copier) Copy(ctx context.Context, request *CopyObjectRequest, optFns ...func(*CopierOptions)) (*CopyResult, error)Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ctx | context.Context | Yes | Request context. Use it to set a deadline or cancel the operation. |
request | *CopyObjectRequest | Yes | Copy request parameters. See CopyObjectRequest. |
optFns | ...func(*CopierOptions) | No | Per-call Copier options that override the instance defaults. See CopierOptions. |
Return values
| Value | Type | Description |
|---|---|---|
result | *CopyResult | Copy result. Available when err is nil. See CopyResult. |
err | error | nil on success. Non-nil if the request fails. |
CopyObjectRequest parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Bucket | *string | Yes | Name of the destination bucket. |
Key | *string | Yes | Name of the destination object. |
SourceBucket | *string | Yes | Name of the source bucket. |
SourceKey | *string | Yes | Name of the source object. |
ForbidOverwrite | *string | No | Set to "true" to prevent overwriting an existing object with the same name. |
StorageClass | — | No | Storage class of the destination object. |
MetadataDirective | *string | No | How to handle object metadata. Copy (default): copy from source. Replace: use values in this request. |
Tagging | *string | No | Tags for the destination object. Format: TagA=A&TagB=B. |
TaggingDirective | *string | No | How to handle object tags. Copy (default): copy from source. Replace: use Tagging in this request. |
CopierOptions parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
PartSize | int64 | No | 64 MiB | Size of each part in a multipart copy. |
ParallelNum | int | No | 3 | Number of parts copied in parallel. Applies to this call only. |
MultipartCopyThreshold | int64 | No | 200 MiB | Objects at or above this size are copied using multipart copy. |
LeavePartsOnError | bool | No | false | When true, already-copied parts are retained if the copy fails. |
DisableShallowCopy | bool | No | false | When true, disables shallow copy and forces a full data copy. |
Usage notes
UploadPartCopydoes not support thex-oss-metadata-directiveorx-oss-tagging-directiverequest headers. To configure metadata or tags during a multipart copy operation, you need additional implementation.The sample code uses the region ID
cn-hangzhou. Replace it with your actual region ID. To access OSS from another Alibaba Cloud service in the same region as the bucket, use an internal endpoint. For details, see Regions and endpoints.