En este tema se describe cómo copiar un objeto de un bucket de origen a un bucket de destino, ya sea el mismo u otro distinto dentro de la misma región.
Notas de uso
En este tema se utiliza el endpoint público de la región China (Hangzhou). Si accede a OSS desde otros servicios de Alibaba Cloud en la misma región, use un endpoint interno. Para más detalles sobre las regiones y los endpoints compatibles, consulte Regions and endpoints.
Este tema muestra cómo crear una instancia de OSSClient con un endpoint de OSS. Para configuraciones alternativas, como usar un dominio personalizado o autenticarse con credenciales de Security Token Service (STS), consulte Create an OssClient.
Cuando un usuario de Resource Access Management (RAM) ejecuta una operación de copia, debe contar con el permiso
oss:GetObjectsobre el objeto de origen. También requiere los permisososs:PutObjectyoss:GetObjecten el bucket de destino. Para más información sobre cómo otorgar políticas personalizadas a un usuario de RAM, consulte Common examples of RAM policies.Los buckets de origen y de destino no deben tener políticas de retención configuradas. De lo contrario, la copia termina con errores y se devuelve el mensaje The object you specified is immutable..
La copia entre regiones no es compatible. Por ejemplo, no es posible copiar un objeto de un bucket en China (Hangzhou) a uno en China (Qingdao).
Copiar un archivo pequeño
A continuación se muestra un código de ejemplo que utiliza el método $ossClient->copyObject para copiar un objeto de menos de 1 GB:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// The endpoint of the China (Hangzhou) region is used in this example. Replace the value with the actual endpoint.
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Specify the name of the source bucket. Example: srcexamplebucket.
$from_bucket = "srcexamplebucket";
// Specify the full path of the source object. The full path cannot contain the bucket name. Example: srcdir/exampleobject.txt.
$from_object = "srcdir/exampleobject.txt";
// Specify the name of the destination bucket that is in the same region as the source bucket. Example: destexamplebucket.
// If you copy an object within the same bucket, make sure that the source and destination bucket names are the same.
$to_bucket = "destexamplebucket";
// Specify the full path of the destination object. The full path cannot contain the bucket name. Example: destdir/exampleobject.txt.
$to_object = "destdir/exampleobject.txt";
$options = array(
'headers'=>array(
// Specify whether to overwrite a destination object that has the same name. In this example, this parameter is set to true to prevent overwriting.
// 'x-oss-forbid-overwrite' => 'true',
// If the ETag of the source object matches the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-match' => '5B3C1A2E053D763E1B002CC****',
// If the ETag of the source object does not match the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-none-match' => '5B3C1A2E053D763E1B002CC****',
// If the specified time is the same as or later than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-unmodified-since' => gmdate('2021-12-09T07:01:56.000Z'),
// If the specified time is earlier than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-modified-since' => gmdate('2021-12-09T07:01:56.000Z'),
// Specify how to configure metadata for the destination object. In this example, this parameter is set to COPY to copy the metadata from the source object to the destination object.
// 'x-oss-metadata-directive' => 'COPY',
// Specify the server-side encryption algorithm that OSS uses to create the destination object.
// 'x-oss-server-side-encryption' => 'KMS',
// The customer master key (CMK) managed by KMS. This parameter is valid only when x-oss-server-side-encryption is set to KMS.
// 'x-oss-server-side-encryption-key-id' => '9468da86-3509-4f8d-a61e-6eab****',
// Specify the access permissions for the destination object. In this example, this parameter is set to private. This means only the object owner and authorized users have read and write permissions. Other users cannot access the object.
// 'x-oss-object-acl' => 'private',
// Specify the storage class of the object. In this example, this parameter is set to Standard.
// 'x-oss-storage-class' => 'Standard',
// Specify the tags for the object. You can specify multiple tags.
// 'x-oss-tagging' => 'k1=v1&k2=v2&k3=v3',
// Specify how to configure tags for the destination object. In this example, this parameter is set to COPY to copy the tags from the source object to the destination object.
// 'x-oss-tagging-directive' => 'COPY',
),
);
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$ossClient->copyObject($from_bucket, $from_object, $to_bucket, $to_object);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
Copiar un archivo grande
Para objetos mayores a 1 GB, utilice la copia por partes (UploadPartCopy). Este proceso consta de tres pasos:
Llame a
$ossClient->initiateMultipartUploadpara inicializar una tarea de copia por partes.Llame a
$ossClient->uploadPartCopypara copiar las partes. Todas las partes, excepto la última, deben superar los 100 KB.Llame a
$ossClient->completeMultipartUploadpara confirmar la tarea de copia por partes.
El siguiente código de ejemplo muestra cómo ejecutar una copia por partes:
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;
// Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
$provider = new EnvironmentVariableCredentialsProvider();
// The endpoint of the China (Hangzhou) region is used in this example. Replace the value with the actual endpoint.
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// Specify the name of the source bucket.
$from_bucket = "yourSrcBucketName";
// Specify the full path of the source object. The full path cannot contain the bucket name. Example: srcdir/exampleobject.txt.
$from_object = "yourSrcObjectName";
// Specify the name of the destination bucket that is in the same region as the source bucket.
$to_bucket = "yourDestBucketName";
// Specify the full path of the destination object. The full path cannot contain the bucket name. Example: destdir/exampleobject.txt.
$to_object = 'yourDestObjectName';
// Set the part size in bytes as needed.
$part_size = 256*1024*1024;
try{
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
"signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
$objectMeta = $ossClient->getObjectMeta($from_bucket, $from_object);
$length = $objectMeta['content-length'] + 0;
// Initialize the multipart copy task.
$upload_id = $ossClient->initiateMultipartUpload($to_bucket, $to_object);
// Copy parts.
$pieces = $ossClient->generateMultiuploadParts($length, $part_size);
$response_upload_part = array();
$copyId = 1;
$upload_position = 0;
foreach ($pieces as $i => $piece) {
$from_pos = $upload_position + (integer)$piece['seekTo'];
$to_pos = (integer)$piece['length'] + $from_pos - 1;
$up_options = array(
'start' => $from_pos,
'end' => $to_pos,
'headers'=>array(
// If the ETag of the source object matches the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-match' => '5B3C1A2E053D763E1B002CC****',
// If the ETag of the source object does not match the ETag that you specify, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-none-match' => '5B3C1A2E053D763E1B002CC****',
// If the specified time is the same as or later than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-unmodified-since' => gmdate('2021-12-09T07:01:56.000Z'),
// If the specified time is earlier than the actual modification time of the object, OSS copies the object and returns 200 OK.
// 'x-oss-copy-source-if-modified-since' => gmdate('2021-12-09T07:01:56.000Z'),
),
);
$response_upload_part[] = $ossClient->uploadPartCopy( $from_bucket, $from_object, $to_bucket, $to_object, $copyId, $upload_id, $up_options);
$copyId = $copyId + 1;
}
// Complete the multipart copy.
$upload_parts = array();
foreach ($response_upload_part as $i => $etag) {
$upload_parts[] = array(
'PartNumber' => ($i + 1),
'ETag' => $etag,
);
}
$result = $ossClient->completeMultipartUpload($to_bucket, $to_object, $upload_id, $upload_parts);
} catch(OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": OK" . "\n");
Referencias
-
Copiar un archivo pequeño
Para consultar el código de ejemplo completo sobre cómo copiar un archivo pequeño, visite GitHub.
Para más información sobre la operación de API que permite copiar un archivo pequeño, consulte CopyObject.
-
Copiar un archivo grande
Para consultar el código de ejemplo completo sobre cómo copiar un archivo grande, visite GitHub.
Para más información sobre la operación de API que permite copiar un archivo grande, consulte UploadPartCopy.