Este tópico descreve como copiar um objeto de um bucket de origem para o mesmo bucket ou para um bucket de destino diferente na mesma região.
Observações de uso
Este tópico utiliza o endpoint público da região China (Hangzhou). Para acessar o OSS a partir de outros serviços da Alibaba Cloud na mesma região, use um endpoint interno. Para obter detalhes sobre regiões e endpoints compatíveis, consulte Regions and endpoints.
Este tópico demonstra como criar uma instância OSSClient com um endpoint do OSS. Para configurações alternativas, como usar um domínio personalizado ou autenticar-se com credenciais do Security Token Service (STS), consulte Create an OssClient.
Ao executar uma operação de cópia, o usuário do Resource Access Management (RAM) deve ter a permissão
oss:GetObjectno objeto de origem. Além disso, o usuário deve ter as permissõesoss:PutObjecteoss:GetObjectno bucket de destino. Para obter mais informações sobre como conceder políticas personalizadas a um usuário do RAM, consulte Common examples of RAM policies.Os buckets de origem e de destino não podem ter políticas de retenção configuradas. Caso contrário, a cópia falha e retorna o erro The object you specified is immutable.
Não há suporte para cópia entre regiões. Por exemplo, não é possível copiar um objeto de um bucket em China (Hangzhou) para um bucket em China (Qingdao).
Copiar um arquivo pequeno
O código de exemplo a seguir mostra como usar o método $ossClient->copyObject para copiar um objeto menor que 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 um arquivo grande
Para objetos maiores que 1 GB, use a cópia em várias partes (UploadPartCopy). O processo consiste em três etapas:
Chame o método
$ossClient->initiateMultipartUploadpara inicializar uma tarefa de cópia em várias partes.Chame o método
$ossClient->uploadPartCopypara copiar as partes. Todas as partes, exceto a última, devem ser maiores que 100 KB.Chame o método
$ossClient->completeMultipartUploadpara concluir a tarefa de cópia em várias partes.
O código de exemplo a seguir mostra como executar uma cópia em várias 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");
Referências
-
Copiar um arquivo pequeno
Para obter o código de exemplo completo para copiar um arquivo pequeno, consulte o GitHub.
Para mais detalhes sobre a operação de API para copiar um arquivo pequeno, consulte CopyObject.
-
Copiar um arquivo grande
Para acessar o código de exemplo completo para copiar um arquivo grande, consulte o GitHub.
Para obter mais informações sobre a operação de API para copiar um arquivo grande, consulte UploadPartCopy.