复制对象 - Amazon Simple Storage Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

复制对象

复制操作将创建已存储在 Amazon S3 中的数据元的副本。

在单个原子操作中,您可以创建最大 5 GB 的对象副本。但是,要复制大于 5 GB 的对象,您必须使用分段上传 API。

通过使用 copy 操作,您可以:

  • 创建对象的其他副本

  • 通过复制对象并删除原始对象来重命名它们。

  • 跨不同的 Amazon S3 位置(例如,us-west-1 和欧洲)移动对象

  • 更改对象元数据

    每个 Amazon S3 对象都有元数据。它是一组名称值对。您可以在上传对象元数据时对其进行设置。上传对象后,您将无法修改对象元数据。修改对象元数据的唯一方式是创建对象的副本并设置元数据。在复制操作中,设置与源和目标相同的对象。

每个对象都带有元数据。有些是系统元数据,而另外一些则是用户定义的元数据。您可以控制某些系统元数据,例如,用于对象的存储类配置,并且可以配置服务器端加密。复制对象时,还会复制用户控制的系统元数据和用户定义的元数据。Amazon S3 将重置系统控制的元数据。例如,在复制对象时,Amazon S3 将重置已复制对象的创建日期。在复制请求中,您无需设置这些值。

复制对象时,您可能会决定更新某些元数据值。例如,如果您的源对象被配置为使用 S3 Standard 存储,您可以选择对对象复制使用 S3 Intelligent-Tiering。您可能还会决定更改源对象上某些用户定义的元数据值。请注意,如果您选择在复制期间更新任意对象的用户可配置元数据(系统或用户定义的元数据),则必须显式指定请求中源对象上存在的所有用户可配置的元数据,即使您只更改其中一个元数据值也是如此。

有关对象元数据的详细信息,请参阅 使用对象元数据

注意

在复制对象时,您可以请求 Amazon S3 保存使用 Amazon KMS key、Amazon S3 托管加密密钥或客户提供的加密密钥进行加密的目标对象。因此,您必须在请求中指定加密信息。如果复制源是通过客户提供的密钥使用服务器端加密存储在 Amazon S3 中的对象,则您必须在请求中提供加密信息,以便 Amazon S3 可以解密对象进行复制。有关更多信息,请参阅使用加密保护数据

复制对象时,可以选择对对象使用不同的校验和算法。无论您选择使用相同的算法还是新算法,Amazon S3 都会在复制对象后计算一个新的校验和值。Amazon S3 不会直接复制校验和的值。使用分段上传加载的对象的校验和值可能会发生变化。有关如何计算此校验和的更多信息,请参阅使用分段级别墅校验和进行分段上传

要使用单个请求复制多个 Amazon S3 对象,您可以使用 Amazon S3 分批操作。您为 S3 分批操作提供要操作的对象列表。S3 分批操作调用相应的 API 来执行指定的操作。单个分批操作任务可对包含 EB 级数据的数十亿个对象执行指定操作。

S3 分批操作包括跟踪进度、发送通知并存储所有操作的详细完成报告,从而提供完全托管、可审核的无服务器体验。您可以通过 Amazon Web Services Management Console、Amazon CLI、Amazon SDK 或 REST API 使用 S3 分批操作。有关更多信息,请参阅S3 分批操作基础知识

复制对象

要复制对象,请使用以下方法。

在 Amazon S3 控制台中,您可以复制或移动对象。有关更多信息,请参阅以下流程。

注意

无法使用 S3 控制台复制或移动使用客户提供的加密密钥 (SSE-C) 加密的对象。要复制或移动使用 SSE-C 加密的对象,请使用 Amazon CLI、Amazon SDK 或 Amazon S3 REST API。

复制对象

  1. 登录到 Amazon Web Services Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

  2. 导航到包含待复制对象的 Amazon S3 Bucket 或文件夹。

  3. 选中要复制的对象名称左侧的复选框。

  4. 请选择 Actions(操作),然后从显示的选项列表中选择 Copy(复制)。

    或者,从右上角的选项中选择 Copy(复制)。

  5. 选择目标类型和目标账户。要指定目标路径,请选择 Browse S3 (浏览 S3),导航到目标,然后选中目标左侧的复选框。请选择右下角的 Choose destination(选择目标)。

    或者,输入目标路径。

  6. 如果启用存储桶版本控制,则系统可能会要求您确认是否覆盖具有相同名称的现有对象。如果可以覆盖,请选中该复选框并继续。如果要在此存储桶中保留对象的所有版本,请选择 Enable Bucket Versioning (启用存储桶版本控制)。您还可以更新默认加密和 S3 对象锁定属性。

  7. Additional checksums(其他校验和)下,选择是要使用现有校验和函数复制对象,还是用新校验和函数替换现有校验和函数。上传对象时,您可以选择指定用于验证数据完整性的校验和算法。复制对象时,您可以选择新函数。如果您最初没有指定额外的校验和,则可以使用复制选项的这一部分添加一个校验和。

    注意

    即使您选择使用相同的校验和函数,如果您复制对象且对象大小超过 16 MB,校验和值也可能会发生变化。由于分段上传的校验和计算方式的原因,校验和值可能会发生变化。有关在复制对象时校验和可能会如何变化的信息,请参阅使用分段级别墅校验和进行分段上传

    要更改校验和函数,请选择 Replace with a new checksum function(用新的校验和函数替换)。从框中选择新的校验和函数。复制对象时,将使用指定的算法计算和存储新校验和。

  8. 在右下角,选择 Copy(复制)。Amazon S3 会将对象复制到目标。

移动对象

  1. 登录到 Amazon Web Services Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

  2. 导航到包含待移动对象的 Amazon S3 Bucket 或文件夹。

  3. 选中要移动的对象名称左侧的复选框。

  4. 请选择 Actions(操作),然后从显示的选项列表中选择 Move(移动)。

    或者,从右上角的选项中选择 Move(移动)。

  5. 要指定目标路径,请选择 Browse S3 (浏览 S3),导航到目标,然后选中目标左侧的复选框。请选择右下角的 Choose destination(选择目标)。

    或者,输入目标路径。

  6. 如果启用存储桶版本控制,则系统可能会要求您确认是否覆盖具有相同名称的现有对象。如果可以覆盖,请选中该复选框并继续。如果要在此存储桶中保留对象的所有版本,请选择 Enable Bucket Versioning (启用存储桶版本控制)。您还可以更新默认加密和对象锁定属性。

  7. 选择右下角的 Move(移动)。Amazon S3 将您的对象移动到目标位置。

注意
  • 此操作创建具有更新设置的所有指定对象的副本,更新指定位置的上次修改日期,然后向原始对象添加删除标记。

  • 移动文件夹时,请等待移动操作完成,然后再对文件夹进行其他更改。

  • 此操作会更新存储桶版本控制、加密、对象锁定功能和归档对象的元数据。

本节中的示例向您展示了如何复制单个操作中大于 5 GB 的对象。对于复制大于 5 GB 的对象,您必须使用分段上传 API。有关更多信息,请参阅使用分段上传复制对象

Java

以下示例使用 Amazon SDK for Java 复制 Amazon S3 中的对象。有关创建和测试有效示例的说明,请参阅测试 Amazon S3 Java 代码示例

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.CopyObjectRequest; import java.io.IOException; public class CopyObjectSingleOperation { public static void main(String[] args) throws IOException { Regions clientRegion = Regions.DEFAULT_REGION; String bucketName = "*** Bucket name ***"; String sourceKey = "*** Source object key *** "; String destinationKey = "*** Destination object key ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); // Copy the object into a new object in the same bucket. CopyObjectRequest copyObjRequest = new CopyObjectRequest(bucketName, sourceKey, bucketName, destinationKey); s3Client.copyObject(copyObjRequest); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }
.NET

以下 C# 示例使用高级别 Amazon SDK for .NET 在单次操作中复制最大为 5 GB 的对象。对于大于 5 GB 的对象,请使用 使用分段上传复制对象 中所述的分段上传复制示例。

此示例将创建最大为 5 GB 的对象的副本。有关示例与特定版本的适用于 .NET 的 Amazon 软件开发工具包的兼容性信息,以及有关如何创建和测试有效示例的说明,请参阅运行 Amazon S3 .NET 代码示例

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class CopyObjectTest { private const string sourceBucket = "*** provide the name of the bucket with source object ***"; private const string destinationBucket = "*** provide the name of the bucket to copy the object to ***"; private const string objectKey = "*** provide the name of object to copy ***"; private const string destObjectKey = "*** provide the destination object key name ***"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 s3Client; public static void Main() { s3Client = new AmazonS3Client(bucketRegion); Console.WriteLine("Copying an object"); CopyingObjectAsync().Wait(); } private static async Task CopyingObjectAsync() { try { CopyObjectRequest request = new CopyObjectRequest { SourceBucket = sourceBucket, SourceKey = objectKey, DestinationBucket = destinationBucket, DestinationKey = destObjectKey }; CopyObjectResponse response = await s3Client.CopyObjectAsync(request); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); } } } }
PHP

此主题将指导您使用第 3 版 Amazon SDK for PHP,将 Amazon S3 中的单个对象和多个对象从一个存储桶复制到另一个存储桶或者在同一存储桶中进行复制。

本主题假定您已按照 使用Amazon SDK for PHP和运行 PHP 示例 的说明执行操作,并正确安装了 Amazon SDK for PHP。

以下 PHP 示例演示使用 copyObject() 方法复制 Amazon S3 中的单个对象,使用 getcommand() 方法对 CopyObject 进行批量调用来创建对象的多个副本。

1

使用 Aws\S3\S3Client 类构造函数创建 Amazon S3 客户端的实例。

2

要创建对象的多个副本,请运行对 Amazon S3 客户端 getCommand() 方法的批量调用,该方法是从 Aws\CommandInterface 类继承的。您提供 CopyObject 命令作为第一个参数,提供包含源存储桶、源键名、目标存储桶和目标键名的数组作为第二个参数。

require 'vendor/autoload.php'; use Aws\S3\S3Client; $sourceBucket = '*** Your Source Bucket Name ***'; $sourceKeyname = '*** Your Source Object Key ***'; $targetBucket = '*** Your Target Bucket Name ***'; $s3 = new S3Client([ 'version' => 'latest', 'region' => 'us-east-1' ]); // Copy an object. $s3->copyObject([ 'Bucket' => $targetBucket, 'Key' => "{$sourceKeyname}-copy", 'CopySource' => "{$sourceBucket}/{$sourceKeyname}", ]); // Perform a batch of CopyObject operations. $batch = array(); for ($i = 1; $i <= 3; $i++) { $batch[] = $s3->getCommand('CopyObject', [ 'Bucket' => $targetBucket, 'Key' => "{targetKeyname}-{$i}", 'CopySource' => "{$sourceBucket}/{$sourceKeyname}", ]); } try { $results = CommandPool::batch($s3, $batch); foreach($results as $result) { if ($result instanceof ResultInterface) { // Result handling here } if ($result instanceof AwsException) { // AwsException handling here } } } catch (\Exception $e) { // General error handling here }
Ruby

以下任务将引导您使用 Ruby 类将 Amazon S3 中的对象从一个存储桶复制到另一存储桶,或者在同一个存储桶内复制。

1

对第 3 版 Amazon SDK for Ruby 使用 Amazon S3 模块化 Gem 时,需要“aws-sdk-s3”并提供您的 Amazon 凭证。有关如何提供您的凭证的更多信息,请参阅 使用 Amazon Web Services 账户 或 IAM 用户凭证发出请求

2

提供源存储桶名称、源键名、目标存储桶名称和目标键等请求信息。

下面的 Ruby 代码示例通过使用 #copy_object 方法将对象从一个存储桶复制到另一个存储桶,演示了上述任务。

require "aws-sdk-s3" # Wraps Amazon S3 object actions. class ObjectCopyWrapper attr_reader :source_object # @param source_object [Aws::S3::Object] An existing Amazon S3 object. This is used as the source object for # copy actions. def initialize(source_object) @source_object = source_object end # Copy the source object to the specified target bucket and rename it with the target key. # # @param target_bucket [Aws::S3::Bucket] An existing Amazon S3 bucket where the object is copied. # @param target_object_key [String] The key to give the copy of the object. # @return [Aws::S3::Object, nil] The copied object when successful; otherwise, nil. def copy_object(target_bucket, target_object_key) @source_object.copy_to(bucket: target_bucket.name, key: target_object_key) target_bucket.object(target_object_key) rescue Aws::Errors::ServiceError => e puts "Couldn't copy #{@source_object.key} to #{target_object_key}. Here's why: #{e.message}" end end # Replace the source and target bucket names with existing buckets you own and replace the source object key # with an existing object in the source bucket. def run_demo source_bucket_name = "doc-example-bucket1" source_key = "my-source-file.txt" target_bucket_name = "doc-example-bucket2" target_key = "my-target-file.txt" source_bucket = Aws::S3::Bucket.new(source_bucket_name) wrapper = ObjectCopyWrapper.new(source_bucket.object(source_key)) target_bucket = Aws::S3::Bucket.new(target_bucket_name) target_object = wrapper.copy_object(target_bucket, target_key) return unless target_object puts "Copied #{source_key} from #{source_bucket_name} to #{target_object.bucket_name}:#{target_object.key}." end run_demo if $PROGRAM_NAME == __FILE__

本示例描述了如何使用 REST 复制对象。有关 REST API 的更多信息,请参阅 PUT Object (Copy)

本示例将 flotsam 存储桶中的 pacific 对象复制到 jetsam 存储桶的 atlantic 对象,同时保留其元数据。

PUT /jetsam HTTP/1.1 Host: atlantic.s3.amazonaws.com x-amz-copy-source: /pacific/flotsam Authorization: AWS AKIAIOSFODNN7EXAMPLE:ENoSbxYByFA0UGLZUqJN5EUnLDg= Date: Wed, 20 Feb 2008 22:12:21 +0000

将从以下信息生成签名。

PUT\r\n \r\n \r\n Wed, 20 Feb 2008 22:12:21 +0000\r\n x-amz-copy-source:/pacific/flotsam\r\n /atlantic/jetsam

Amazon S3 将返回以下响应来指定对象的 ETag 及其上次修改的时间。

HTTP/1.1 200 OK x-amz-id-2: Vyaxt7qEbzv34BnSu5hctyyNSlHTYZFMWK4FtzO+iX8JQNyaLdTshL0KxatbaOZt x-amz-request-id: 6B13C3C5B34AF333 Date: Wed, 20 Feb 2008 22:13:01 +0000 Content-Type: application/xml Transfer-Encoding: chunked Connection: close Server: AmazonS3 <?xml version="1.0" encoding="UTF-8"?> <CopyObjectResult> <LastModified>2008-02-20T22:13:01</LastModified> <ETag>"7e9c608af58950deeb370c98608ed097"</ETag> </CopyObjectResult>