本文介绍如何拷贝文件。

拷贝文件的完整代码请参见GitHub

同一存储空间内拷贝文件

以下代码用于在同一个存储空间内拷贝文件:

package main

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

func main() {
	// 创建OSSClient实例。
	client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	bucketName := "<yourBucketName>"
	objectName := "<yourObjectName>"
	destObjectName := "<yourDestObjectName>"

	// 获取存储空间。
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 拷贝文件到同一个存储空间的另一个文件。
	_, err = bucket.CopyObject(objectName, destObjectName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

跨存储空间拷贝文件

您可以将其它存储空间的文件拷贝到当前存储空间,也可以将当前存储空间的文件拷贝到其它存储空间。代码如下:

package main

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

func main() {
	// 创建OSSClient实例。
	client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	bucketName := "<yourBucketName>"
	srcBucketName := "<yourSrcBucketName>"
	dstBucketName := "<yourDstBucketName>"
	srcObjectName := "<yourSrcObjectName>"
	dstObjectName := "<yourDstObjectName>"

	// 获取存储空间。
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 从其它存储空间(srcBucketName)拷贝源文件(srcObjectName)到本存储空间。
	bucket.CopyObjectFrom(srcBucketName, srcObjectName, dstObjectName)
	if err != nil {
		fmt.Println("CopyObjectFrom Error:", err)
		os.Exit(-1)
	}

	// 从本存储空间拷贝源文件(srcObjectName)到其它存储空间(dstBucketName)。
	bucket.CopyObjectTo(dstBucketName, dstObjectName, srcObjectName)
	if err != nil {
		fmt.Println("CopyObjectTo Error:", err)
		os.Exit(-1)
	}
}

拷贝时处理文件元信息

您可以在拷贝文件时通过MetadataDirective参数来处理文件元信息。MetadataDirective的取值如下:

  • oss.MetaCopy:默认值。目标文件的元信息与源文件的元信息相同,即拷贝源文件的元信息。
  • oss.MetaReplace:使用指定的元信息覆盖源文件的元信息。
注意 oss.MetaReplace将覆盖源文件的全部元信息,且无法恢复,请谨慎操作。

MetadataDirective取值为oss.MetaReplace时,可以指定的元信息如下:

参数 说明
CacheControl 指定目标文件被下载时的网页的缓存行为。
ContentDisposition 指定目标文件被下载时的名称。
ContentEncoding 指定目标文件被下载时的内容编码格式。
Expires 设置缓存过期时间,格式是格林威治时间(GMT)。
ServerSideEncryption 指定OSS创建目标文件时的服务器端加密编码算法。有效值:AES256。
ObjectACL 指定OSS创建的目标文件的访问权限。
Meta 自定义元信息,以X-Oss-Meta-为前缀的参数。

以下代码用于在拷贝时处理文件元信息:

package main

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

func main() {
	// 创建OSSClient实例。
	client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	bucketName := "<yourBucketName>"
	objectName := "<yourObjectName>"
	destObjectName := "<yourDestObjectName>"

	// 获取存储空间。
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 指定目标文件的元信息。
	expires := time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
	options := []oss.Option{
		oss.MetadataDirective(oss.MetaReplace),
		oss.Expires(expires),
		oss.ObjectACL(oss.ACLPublicRead),
		oss.Meta("MyMeta", "MyMetaValue")}

	// 使用指定的元信息覆盖源文件的元信息。
	_, err = bucket.CopyObject(objectName, destObjectName, options...)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

限定条件拷贝

拷贝文件时,可以指定一个或多个限定条件。满足限定条件则拷贝,不满足则返回错误,不拷贝。可以使用的限定条件如下:

参数 说明
CopySourceIfMatch 如果源文件的ETag和指定的ETag匹配,则执行拷贝操作;否则返回错误。
CopySourceIfNoneMatch 如果源文件的ETag和指定的ETag不匹配,则执行拷贝操作;否则返回错误。
CopySourceIfModifiedSince 如果指定的时间早于实际修改时间,则执行拷贝操作;否则返回错误。
CopySourceIfUnmodifiedSince 如果指定的时间等于或者晚于文件实际修改时间,则执行拷贝操作;否则返回错误。

CopySourceIfMatch和CopySourceIfNoneMatch可以同时存在。CopySourceIfModifiedSince和CopySourceIfUnmodifiedSince可以同时存在。

以下代码用于限定条件拷贝:

package main

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

func main() {
	// 创建OSSClient实例。
	client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// bucketName := "<yourBucketName>"
	// objectName := "<yourObjectName>"
	bucketName := "<yourBucketName>"
	objectName := "<yourObjectName>"
	destMatchObjectName := "<yourMatchDestObjectName>"
	destUnMatchObjectName := "<yourUnmatchDestObjectName>"

	// 获取存储空间。
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	date := time.Date(2011, time.November, 10, 23, 0, 0, 0, time.UTC)

	// 满足限定条件,执行拷贝。
	_, err = bucket.CopyObject(objectName, destMatchObjectName, oss.CopySourceIfModifiedSince(date))
	if err != nil {
		fmt.Println("CopyObject CopySourceIfModifiedSince Error:", err)
	}

	// 不满足限定条件,不执行拷贝。
	_, err = bucket.CopyObject(objectName, destUnMatchObjectName, oss.CopySourceIfUnmodifiedSince(date))
	if err != nil {
		fmt.Println("CopyObject CopySourceIfUnmodifiedSince Error:", err)
	}
}