复制、移动和重命名对象 - Amazon Simple Storage Service

复制、移动和重命名对象

CopyObject 操作将创建已存储在 Amazon S3 中的对象的副本。

在单个原子操作中,您可以创建最大 5GB 的对象副本。但是,要复制大于 5 GB 的对象,必须通过 AWS CLI 或 AWS SDK 使用分段上传。有关更多信息,请参阅 使用分段上传复制对象

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

  • 创建对象的其它副本。

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

  • 将对象从一个存储桶复制或移动到另一个存储桶,包括跨 AWS 区域(例如,从 us-west-1eu-west-2)。移动对象时,Amazon S3 将对象复制到指定目标,然后删除源对象。

    注意

    跨 AWS 区域复制或移动对象会产生带宽费用。有关更多信息,请参阅 Amazon S3 定价

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

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

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

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

复制已存档和已还原的对象

如果源对象归档在 S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive 中,您必须先还原临时副本,然后才能将对象复制到另一个存储桶中。有关对象归档的更多信息,请参阅 使用归档的对象

在 Amazon S3 控制台中,不支持对 S3 Glacier Flexible Retrieval 或 S3 Glacier Deep Archive 存储类中的已还原对象执行复制操作。要复制这些已还原对象,请使用 AWS Command Line Interface(AWS CLI)、AWS SDK 或 Amazon S3 REST API。

复制加密对象

Amazon S3 会自动加密所有复制到 S3 存储桶的新对象。如果您未在复制请求中指定加密信息,则目标对象的加密设置将设为目标存储桶的默认加密配置。默认情况下,所有存储桶都有基本级别的加密配置,该配置使用具有 Amazon S3 托管密钥的服务器端加密(SSE-S3)。如果目标存储桶的默认加密配置使用具有 AWS Key Management Service(AWS KMS)密钥(SSE-KMS)或客户提供加密密钥(SSE-C)的服务器端加密,则 Amazon S3 使用相应的 KMS 密钥或客户提供的密钥来加密目标对象副本。

在复制对象时,如果您希望对目标对象使用其他类型的加密设置,您可以请求 Amazon S3 使用 KMS 密钥、Amazon S3 托管式密钥或客户提供的密钥对目标对象加密。如果您的请求中的加密设置与目标存储桶的默认加密配置不同,则您的请求中的加密设置优先。如果副本的源对象是用 SSE-C 加密的,您必须在请求中提供必需的加密信息,以便 Amazon S3 可以解密对象以进行复制。有关更多信息,请参阅 利用加密来保护数据

复制对象时使用校验和

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

在单个请求中复制多个对象

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

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

将对象复制到目录存储桶

有关将对象复制到目录存储桶的信息,请参阅将对象复制到目录存储桶。有关将 Amazon S3 Express One Zone 存储类与目录存储桶结合使用的信息,请参阅目录存储桶和 S3 Express One Zone目录存储桶概述

复制对象

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

注意

使用控制台复制对象时的限制和局限性如下所示:

  • 如果对象小于 5 GB,则可以复制对象。如果对象大于 5GB,则必须使用 AWS CLIAWS SDK 来复制对象。

  • 有关复制对象所需的其它权限的列表,请参阅 Amazon S3 API 操作所需的权限。有关授予此权限的示例策略,请参阅Amazon S3 基于身份的策略示例

  • Copy 操作适用于指定文件夹(前缀)中的所有对象。当正在执行操作时添加到这些文件夹的对象可能受到影响。

  • Amazon S3 控制台不支持跨区域复制使用 SSE-KMS 加密的对象。要跨区域复制使用 SSE-KMS 加密的对象,请使用 AWS CLI、AWS SDK 或 Amazon S3 REST API。

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

  • 复制的对象将不会保留原始对象的对象锁定设置。

  • 如果要从中复制对象的存储桶对于 S3 对象所有权使用“强制存储桶拥有者”设置,则对象 ACL 将不会复制到指定的目标。

  • 如果要将对象复制到对于 S3 对象所有权使用“强制存储桶拥有者”设置的存储桶,请确保源存储桶也使用“强制存储桶拥有者”设置,或移除对其它 AWS 账户和组的任何对象 ACL 授权。

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

  2. 在左侧导航窗格中,选择存储桶,然后选择通用存储桶选项卡。导航到包含待复制对象的 Amazon S3 存储桶或文件夹。

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

  4. 操作菜单上,从显示的选项列表中选择复制

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

    或者,输入目标路径。

  6. 如果您 启用存储桶版本控制,则会看到一则警告,建议您启用存储桶版本控制,以防意外覆盖或删除对象。如果要在此存储桶中保留对象的所有版本,请选择 Enable Bucket Versioning(启用存储桶版本控制)。还可以在目标详细信息中查看默认加密和 S3 对象锁定属性。

  7. 其它复制设置下,选择是要复制源设置请勿指定设置还是指定设置复制源设置是默认选项。如果您只想复制不带源设置属性的对象,请选择请勿指定设置。选择指定设置,来指定存储类、ACL、对象标签、元数据、服务器端加密和其它校验和的设置。

  8. 选择右下角的复制。Amazon S3 会将对象复制到目标。

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

Java

以下示例使用 AWS SDK for Java 复制 Amazon S3 中的对象。有关创建和测试有效示例的说明,请参阅《AWS SDK for 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# 示例使用高级别 AWS SDK for .NET 在单次操作中复制最大为 5 GB 的对象。对于大于 5 GB 的对象,请使用 使用分段上传复制对象 中所述的分段上传复制示例。

此示例将创建最大为 5 GB 的对象的副本。有关设置和运行代码示例的信息,请参阅《适用于 .NET 的 AWS SDK 开发人员指南》中的适用于 .NET 的 AWS SDK 入门

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 版 AWS SDK for PHP,将 Amazon S3 中的单个对象和多个对象从一个存储桶复制到另一个存储桶或者在同一存储桶中进行复制。

有关适用于 Ruby 的 AWS 开发工具包 API 的更多信息,请转到适用于 Ruby 的 AWS 开发工具包 – 版本 2

以下 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\CommandPool; use Aws\Exception\AwsException; use Aws\ResultInterface; 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 }
Python
class ObjectWrapper: """Encapsulates S3 object actions.""" def __init__(self, s3_object): """ :param s3_object: A Boto3 Object resource. This is a high-level resource in Boto3 that wraps object actions in a class-like structure. """ self.object = s3_object self.key = self.object.key
def copy(self, dest_object): """ Copies the object to another bucket. :param dest_object: The destination object initialized with a bucket and key. This is a Boto3 Object resource. """ try: dest_object.copy_from( CopySource={"Bucket": self.object.bucket_name, "Key": self.object.key} ) dest_object.wait_until_exists() logger.info( "Copied object from %s:%s to %s:%s.", self.object.bucket_name, self.object.key, dest_object.bucket_name, dest_object.key, ) except ClientError: logger.exception( "Couldn't copy object from %s/%s to %s/%s.", self.object.bucket_name, self.object.key, dest_object.bucket_name, dest_object.key, ) raise
Ruby

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

复制对象

1

对 AWS SDK for Ruby 的版本 3 使用 Amazon S3 模块化 Gem 时,需要 aws-sdk-s3 并提供您的 AWS 凭证。有关如何提供凭证的更多信息,请参阅《Amazon S3 API 参考》中的 Making requests using AWS account or IAM user credentials

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 # Example usage: def run_demo source_bucket_name = "amzn-s3-demo-bucket1" source_key = "my-source-file.txt" target_bucket_name = "amzn-s3-demo-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__

本示例描述了如何使用 Amazon S3 REST API 复制对象。有关 REST API 的更多信息,请参阅CopyObject

本示例将 flotsam 存储桶中的 amzn-s3-demo-bucket1 对象复制到 jetsam 存储桶的 amzn-s3-demo-bucket2 对象,同时保留其元数据。

PUT /jetsam HTTP/1.1 Host: amzn-s3-demo-bucket2.s3.amazonaws.com x-amz-copy-source: /amzn-s3-demo-bucket1/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:/amzn-s3-demo-bucket1/flotsam\r\n /amzn-s3-demo-bucket2/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>

也可以使用 AWS Command Line Interface(AWS CLI)复制 S3 对象。有关更多信息,请参阅 AWS CLI 命令参考 中的 copy-object

有关 AWS CLI 的更多信息,请参阅《AWS Command Line Interface 用户指南》中的什么是 AWS Command Line Interface?

移动对象

要移动对象,请使用以下方法。

注意
  • 如果对象小于 5 GB,则可以移动对象。如果对象大于 5GB,必须使用 AWS CLIAWS SDK 来移动对象。

  • 有关移动对象所需的其它权限的列表,请参阅 Amazon S3 API 操作所需的权限。有关授予此权限的示例策略,请参阅Amazon S3 基于身份的策略示例

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

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

  • 您不能使用 S3 接入点别名作为 Amazon S3 控制台中移动操作的源或目标。

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

  2. 在导航窗格中,选择存储桶,然后选择通用存储桶选项卡。导航到包含待移动对象的 Amazon S3 存储桶或文件夹。

  3. 选中要移动的对象所对应的复选框。

  4. 操作菜单上,选择移动

  5. 要指定目标路径,请选择浏览 S3,导航到目标,然后选中目标复选框。选择选择目标

    或者,输入目标路径。

  6. 如果您 启用存储桶版本控制,则会看到一则警告,建议您启用存储桶版本控制,以防意外覆盖或删除对象。如果要在此存储桶中保留对象的所有版本,请选择 Enable Bucket Versioning(启用存储桶版本控制)。还可以在目标详细信息中查看默认加密和对象锁定属性。

  7. 其它复制设置下,选择是要复制源设置请勿指定设置还是指定设置复制源设置是默认选项。如果您只想复制不带源设置属性的对象,请选择请勿指定设置。选择指定设置,来指定存储类、ACL、对象标签、元数据、服务器端加密和其它校验和的设置。

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

您也可以使用 AWS Command Line Interface(AWS CLI)移动 S3 对象。有关更多信息,请参阅 AWS CLI 命令参考 中的 mv

有关 AWS CLI 的更多信息,请参阅《AWS Command Line Interface 用户指南》中的什么是 AWS Command Line Interface?

重命名对象

要重命名对象,请使用以下过程。

注意
  • 如果对象小于 5 GB,则可以重命名对象。要重命名大于 5 GB 的对象,必须使用 AWS CLIAWS SDK 来复制具有新名称的对象,然后删除原始对象。

  • 有关复制对象所需的其它权限的列表,请参阅 Amazon S3 API 操作所需的权限。有关授予此权限的示例策略,请参阅Amazon S3 基于身份的策略示例

  • 重命名对象将创建具有新的上次修改日期的对象副本,然后在原始对象上添加删除标记。

  • 默认加密的存储桶设置会自动应用于任何未加密的指定对象。

  • 您无法使用 Amazon S3 控制台来重命名采用客户提供的加密密钥(SSE-C)的对象。要重命名使用 SSE-C 加密的对象,请使用 AWS CLI、AWS SDK 或 Amazon S3 REST API 以新名称复制这些对象。

  • 如果此存储桶的 S3 对象所有权使用强制存储桶拥有者设置,则不会复制对象访问控制列表(ACL)。

重命名对象
  1. 登录到AWS Management Console,然后通过以下网址打开 Amazon S3 控制台:https://console.aws.amazon.com/s3/

  2. 在导航窗格中,选择存储桶,然后选择通用存储桶选项卡。导航到包含待重命名的对象的 Amazon S3 存储桶或文件夹。

  3. 选择要重命名的对象所对应的复选框。

  4. 操作菜单中,选择重命名对象

  5. 新对象名称框中,输入对象的新名称。

  6. 其它复制设置下,选择是要复制源设置请勿指定设置还是指定设置复制源设置是默认选项。如果您只想复制不带源设置属性的对象,请选择请勿指定设置。选择指定设置,来指定存储类、ACL、对象标签、元数据、服务器端加密和其它校验和的设置。

  7. 选择 Save changes(保存更改)。Amazon S3 随即重命名您的对象。