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

欢迎使用新的 Amazon S3 用户指南! Amazon S3 用户指南结合了以下三个已停用的指南中的信息和说明:Amazon S3 开发人员指南Amazon S3 控制台用户指南Amazon S3 入门指南

复制对象

复制操作将创建已存储在 Amazon S3 中的数据元的副本。在单个原子操作中,您可以创建最大 5 GB 的对象副本。但是,对于复制大于 5 GB 的对象,您必须使用分段上传 API。通过使用 copy 操作,您可以:

  • 创建对象的其他副本

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

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

  • 更改对象元数据

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

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

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

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

注意

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

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

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

复制对象

要复制对象,请使用下面的示例。

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

复制对象

  1. 登录 AWS 管理控制台,并通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

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

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

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

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

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

    或者,输入目标路径。

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

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

移动对象

  1. 登录 AWS 管理控制台,并通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

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

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

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

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

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

    或者,输入目标路径。

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

  7. 选择右下角的 Move (移动),Amazon S3 会将您的对象移动到目的地。

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

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

  • 无法使用 S3 控制台复制使用客户提供的加密密钥 (SSE-C) 加密的对象。要复制使用 SSE-C 加密的对象,请使用 AWS CLI、AWS 开发工具包或 Amazon S3 REST API。

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

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

Java

以下示例使用适用于 Java 的 AWS 开发工具包在 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# 示例演使用适用于 .NET 的高级别 AWS 开发工具包在单个操作中复制最大为 5 GB 的对象。对于大于 5 GB 的对象,请使用 使用分段上传复制对象 中所述的分段上传复制示例。

此示例将创建最大为 5 GB 的对象的副本。要获得关示例与特定版本的适用于 .NET 的 AWS 开发工具包的兼容性的信息以及有关如何创建和测试有效示例的说明,请参阅运行 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

此主题将指导您使用适用于 PHP 的 AWS 开发工具包(版本 3)中的类,将 Amazon S3 中的单个对象和多个对象从一个存储桶复制到另一个存储桶,或者复制到同一存储桶中。

此主题假定您已按照使用适用于 PHP 的 AWS 开发工具包和运行 PHP 示例中的说明执行操作,并正确安装了适用于 PHP 的 AWS 开发工具包。

以下 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

使用适用于 Ruby 的 AWS 开发工具包(版本 3)的 Amazon S3 模块化 Gem,需要“aws-sdk-S3”,并提供您的 AWS 凭证。有关如何提供您的凭证的更多信息,请参阅使用 AWS 账户或 IAM 用户凭证发出请求

2

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

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

require 'aws-sdk-s3' # Copies an object from one Amazon S3 bucket to another. # # Prerequisites: # # - Two S3 buckets (a source bucket and a target bucket). # - An object in the source bucket to be copied. # # @param s3_client [Aws::S3::Client] An initialized Amazon S3 client. # @param source_bucket_name [String] The source bucket's name. # @param source_key [String] The name of the object # in the source bucket to be copied. # @param target_bucket_name [String] The target bucket's name. # @param target_key [String] The name of the copied object. # @return [Boolean] true if the object was copied; otherwise, false. # @example # s3_client = Aws::S3::Client.new(region: 'us-east-1') # exit 1 unless object_copied?( # s3_client, # 'doc-example-bucket1', # 'my-source-file.txt', # 'doc-example-bucket2', # 'my-target-file.txt' # ) def object_copied?( s3_client, source_bucket_name, source_key, target_bucket_name, target_key) return true if s3_client.copy_object( bucket: target_bucket_name, copy_source: source_bucket_name + '/' + source_key, key: target_key ) rescue StandardError => e puts "Error while copying object: #{e.message}" end

本示例描述了如何使用 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>