Puede llamar a la operación UploadPartCopy del SDK for Go 2.0 de Object Storage Service (OSS) para copiar un objeto de un bucket de origen a un bucket de destino en la misma región mediante una copia multipart. El bucket de destino puede ser igual o distinto al bucket de origen.
Notas de uso
El código de ejemplo usa el identificador de región
cn-hangzhoude la región China (Hangzhou) y el endpoint público de forma predeterminada. Para acceder a los recursos mediante otros servicios de Alibaba Cloud en la misma región que el bucket, use el endpoint interno. Para obtener más información sobre las regiones y los endpoints de OSS, consulte Regions and endpoints.Las credenciales de acceso se obtienen de variables de entorno. Para obtener más información sobre cómo configurar las credenciales de acceso, consulte Configure access credentials.
Para copiar un objeto, debe tener permisos de lectura sobre el objeto de origen, así como permisos de lectura y escritura sobre el bucket de destino.
El bucket de origen y el bucket de destino deben ubicarse en la misma región. Por ejemplo, no es posible copiar objetos de un bucket ubicado en la región China (Hangzhou) a otro bucket ubicado en la región China (Qingdao).
Compruebe que no haya políticas de retención configuradas para el bucket de origen ni para el bucket de destino. De lo contrario, se devuelve a continuación mensaje de error: The object you specified is immutable.
Método
func (c *Client) UploadPartCopy(ctx context.Context, request *UploadPartCopyRequest, optFns ...func(*Options)) (*UploadPartCopyResult, error)
Parámetros de solicitud
|
Parámetro |
Tipo |
Descripción |
|
ctx |
context.Context |
Contexto de la solicitud. Permite establecer un tiempo de espera para la solicitud. |
|
request |
*UploadPartCopyRequest |
Parámetros de la solicitud. Para obtener más información, consulte UploadPartCopyRequest. |
|
optFns |
...func(*Options) |
Parámetros opcionales. Para obtener más información, consulte Options. |
Parámetros de respuesta
|
Parámetro |
Tipo |
Descripción |
|
result |
*UploadPartCopyResult |
Respuesta de la operación. Es válido cuando err es nil. Para obtener más información, consulte UploadPartCopyResult. |
|
err |
error |
Mensaje de error. Un valor distinto de nil indica que la solicitud finalizó con errores. |
Proceso de copia multipart
Para copiar un objeto mediante una copia multipart, siga estos pasos:
-
Inicie una tarea de carga multipart.
Use el método Client.InitiateMultipartUpload para obtener un identificador de carga único en OSS.
-
Cargue las partes.
Use el método Client.UploadPartCopy para cargar las partes.
NotaEn las partes que se cargan al ejecutar una tarea de carga multipart con un identificador específico, los números de parte indican su posición relativa dentro del objeto. Si carga una parte y reutiliza su número para cargar otra, la nueva parte sobrescribe a la original.
OSS incluye el hash MD5 de cada parte cargada en el encabezado ETag de la respuesta.
OSS calcula el hash MD5 de las partes cargadas y lo compara con el hash MD5 que calcula el SDK for Go de OSS. Si ambos hashes son distintos, OSS devuelve el código de error InvalidDigest.
-
Complete la tarea de carga multipart.
Una vez que se hayan cargado todas las partes, use el método Client.CompleteMultipartUpload para combinarlas en un objeto completo.
Ejemplos
A continuación se muestra un ejemplo de código que copia un objeto de un bucket de origen a un bucket de destino mediante una copia multipart y combina las partes en un objeto completo:
package main
import (
"context"
"flag"
"log"
"sync"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// Specify the global variables.
var (
region string // The region.
srcBucketName string // The name of the source bucket.
srcObjectName string // The name of the source object.
destBucketName string // The name of the destination bucket.
destObjectName string // The name of the destination object.
)
// Specify the init function used to initialize command line parameters.
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() {
// Parse command line parameters.
flag.Parse()
// Specify the upload ID.
var uploadId string
// Check whether the source bucket name is empty.
if len(srcBucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source bucket name required")
}
// Check whether the region is empty.
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// If the destination bucket name is not specified, the source bucket name is used.
if len(destBucketName) == 0 {
destBucketName = srcBucketName
}
// Check whether the source object name is empty.
if len(srcObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, source object name required")
}
// Check whether the destination object name is empty.
if len(destObjectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, destination object name required")
}
// Load the default configurations and specify the credential provider and region.
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// Create an OSS client.
client := oss.NewClient(cfg)
// Initialize the multipart upload request.
initRequest := &oss.InitiateMultipartUploadRequest{
Bucket: oss.Ptr(destBucketName),
Key: oss.Ptr(destObjectName),
}
initResult, err := client.InitiateMultipartUpload(context.TODO(), initRequest)
if err != nil {
log.Fatalf("failed to initiate multipart upload %v", err)
}
// Display the result of multipart copy.
log.Printf("initiate multipart upload result:%#v\n", *initResult.UploadId)
uploadId = *initResult.UploadId
// Initialize the wait group and mutual exclusion (mutex).
var wg sync.WaitGroup
var parts []oss.UploadPart
count := 3
var mu sync.Mutex
// Start multiple goroutines for multipart upload.
for i := 0; i < count; i++ {
wg.Add(1)
go func(partNumber int, i int) {
defer wg.Done()
// Create the multipart upload request.
partRequest := &oss.UploadPartCopyRequest{
Bucket: oss.Ptr(destBucketName), // The name of the destination bucket.
Key: oss.Ptr(destObjectName), // The name of the destination object.
SourceBucket: oss.Ptr(srcBucketName), // The name of the source bucket.
SourceKey: oss.Ptr(srcObjectName), // The name of the source object.
PartNumber: int32(partNumber), // The part number.
const uploadId = '<Upload Id>'; // The upload ID of the multipart upload task.
}
// Send the multipart upload request.
partResult, err := client.UploadPartCopy(context.TODO(), partRequest)
if err != nil {
log.Fatalf("failed to upload part copy %d: %v", partNumber, err)
}
// Record the multipart upload result.
part := oss.UploadPart{
PartNumber: partRequest.PartNumber,
ETag: partResult.ETag,
}
// Use the mutex to protect shared data.
mu.Lock()
parts = append(parts, part)
mu.Unlock()
}(i+1, i)
}
// Wait until all goroutines are complete.
wg.Wait()
// Complete the multipart upload request.
request := &oss.CompleteMultipartUploadRequest{
Bucket: oss.Ptr(destBucketName),
Key: oss.Ptr(destObjectName),
UploadId: oss.Ptr(uploadId),
CompleteMultipartUpload: &oss.CompleteMultipartUpload{
Parts: parts,
},
}
result, err := client.CompleteMultipartUpload(context.TODO(), request)
if err != nil {
log.Fatalf("failed to complete multipart upload %v", err)
}
// Display the result.
log.Printf("complete multipart upload result:%#v\n", result)
}
Referencias
Para consultar el código de ejemplo completo de la copia multipart, visite GitHub.
Para obtener más información sobre la operación InitiateMultipartUpload, visite InitiateMultipartUpload.
Para obtener más información sobre la operación UploadPartCopy, visite UploadPartCopy.
Para obtener más información sobre la operación CompleteMultipartUpload, visite CompleteMultipartUpload.