本文針對大文件的傳輸場景,介紹如何使用Go SDK V2新增的Copier模塊進行文件拷貝。
注意事項
本文示例代碼以華東1(杭州)的地域ID
cn-hangzhou
為例,默認使用外網Endpoint,如果您希望通過與OSS同地域的其他阿里云產品訪問OSS,請使用內網Endpoint。關于OSS支持的Region與Endpoint的對應關系,請參見OSS地域和訪問域名。本文以從環境變量讀取訪問憑證為例。如何配置訪問憑證,請參見配置訪問憑證。
要進行拷貝文件,您必須擁有源文件的讀權限及目標Bucket的讀寫權限。
不支持跨地域拷貝。例如不能將華東1(杭州)地域存儲空間中的文件拷貝到華北1(青島)地域。
拷貝文件時,您需要確保源Bucket和目標Bucket均未設置合規保留策略,否則報錯The object you specified is immutable.。
方法定義
拷貝管理器介紹
當需要將對象從存儲空間復制到另外一個存儲空間,或者修改對象的屬性時,您可以通過拷貝接口或者分片拷貝接口來完成這個操作。這兩個接口有其適用的場景,例如:
拷貝接口(CopyObject)只適合拷貝 5GiB 以下的對象;
分片拷貝接口(UploadPartCopy)支持拷貝大于5GiB 的對象,但不支持元數據指令(x-oss-metadata-directive)和標簽指令(x-oss-tagging-directive)參數,拷貝時需要主動設置需要復制的元數據和標簽。
Go SDK V2新增拷貝管理器Copier提供了通用的拷貝接口,隱藏了接口的差異和實現細節,可根據拷貝的請求參數自動選擇合適的接口復制對象。Copier的常用方法定義如下:
type Copier struct {
...
}
// 用于創建新的拷貝管理器
func (c *Client) NewCopier(optFns ...func(*CopierOptions)) *Copier
// // 用于拷貝文件
func (c *Copier) Copy(ctx context.Context, request *CopyObjectRequest, optFns ...func(*CopierOptions)) (*CopyResult, error)
請求參數列表
參數名 | 類型 | 說明 |
ctx | context.Context | 請求的上下文,可以用來設置請求的總時限 |
request | *CopyObjectRequest | 設置具體接口的請求參數,具體請參見CopyObjectRequest |
optFns | ...func(*CopierOptions) | (可選)配置選項,具體請參見CopierOptions |
其中,CopyObjectRequest的常用參數列舉如下:
參數名 | 類型 | 說明 |
Bucket | *string | 指定目標存儲空間名稱 |
Key | *string | 指定目標對象名稱 |
SourceBucket | *string | 指定源存儲空間名稱 |
SourceKey | *string | 指定源對象名稱 |
ForbidOverwrite | *string | 指定CopyObject操作時是否覆蓋同名目標Object |
Tagging | *string | 指定Object的對象標簽,可同時設置多個標簽,例如TagA=A&TagB=B。 |
TaggingDirective | *string | 指定如何設置目標Object的對象標簽。取值如下:
|
CopierOptions選項的常用參數列舉如下:
參數名 | 類型 | 說明 |
PartSize | int64 | 指定分片大小,默認值為 64MiB |
ParallelNum | int | 指定上傳任務的并發數,默認值為 3。針對的是單次調用的并發限制,而不是全局的并發限制 |
MultipartCopyThreshold | int64 | 使用分片拷貝的閾值,默認值為 200MiB |
LeavePartsOnError | bool | 當拷貝失敗時,是否保留已拷貝的分片,默認不保留 |
DisableShallowCopy | bool | 不使用淺拷貝行為,默認使用 |
返回值列表
返回值名 | 類型 | 說明 |
result | *CopyResult | 接口返回值,當 err 為nil 時有效,具體請參見CopyResult |
err | error | 請求的狀態,當請求失敗時,err 不為 nil |
示例代碼
您可以使用以下代碼將對象從源存儲空間拷貝到目標存儲空間并修改對象的屬性。
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 // 目標對象名稱
)
// init函數用于初始化命令行參數
func init() {
flag.StringVar(®ion, "region", "", "The region in which 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 len(destBucketName) == 0 {
destBucketName = srcBucketName
}
// 檢查源對象名稱是否為空
if len(srcObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, src object name required")
}
// 檢查目標對象名稱是否為空
if len(destObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, destination object name required")
}
// 配置OSS客戶端
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 創建OSS客戶端
client := oss.NewClient(cfg)
// 創建文件拷貝器
c := client.NewCopier()
// 構建拷貝對象的請求
request := &oss.CopyObjectRequest{
Bucket: oss.Ptr(destBucketName), // 目標存儲空間名稱
Key: oss.Ptr(destObjectName), // 目標對象名稱
SourceKey: oss.Ptr(srcObjectName), // 源對象名稱
SourceBucket: oss.Ptr(srcBucketName), // 源存儲空間名稱
StorageClass: oss.StorageClassStandard, // 指定存儲類型為標準類型
MetadataDirective: oss.Ptr("Replace"), // 不拷貝源對象元數據
TaggingDirective: oss.Ptr("Replace"), // 不拷貝源對象標簽
}
// 執行拷貝對象的操作
result, err := c.Copy(context.TODO(), request)
if err != nil {
log.Fatalf("failed to copy object %v", err) // 如果拷貝失敗,記錄錯誤并退出
}
// 打印拷貝對象的結果
log.Printf("copy object result:%#v\n", result)
}