

# 重命名目录存储桶中的对象
<a name="directory-buckets-objects-rename"></a>

使用 `RenameObject` 操作，您能够以原子方式重命名使用 S3 Express One Zone 存储类的目录存储桶中的现有对象，而无需任何数据移动。您可以通过在同一目录存储桶中将现有对象的名称指定为源，并将该对象的新名称指定为目标，来重命名对象。对于以斜杠 (`/`) 分隔符结尾的对象，`RenameObject` API 操作将不会成功。有关更多信息，请参阅[为 Amazon S3 对象命名](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html)。

无论对象的大小如何，`RenameObject` 操作通常都在毫秒内完成。此功能可加快日志文件管理、媒体处理和数据分析等应用程序的速度。此外，`RenameObject` 还会保留所有对象元数据属性，包括存储类、加密类型、创建日期、上次修改日期以及校验和属性。

**注意**  
仅存储在 S3 Express One Zone 存储类中的对象才支持 `RenameObject`。

 要授予对 `RenameObject` 操作的访问权限，建议您使用 `CreateSession` 操作来进行基于会话的授权。具体而言，您可以在存储桶策略或基于身份的策略中授予对目录存储桶的 `s3express:CreateSession` 权限。然后，您对目录存储桶进行 `CreateSession` API 调用以获取会话令牌。使用请求标头中的会话令牌，您可以向此操作发出 API 请求。会话令牌过期后，进行另一次 `CreateSession` API 调用，以生成新的会话令牌供使用。AWS CLI 和 AWS SDK 将创建和管理您的会话（包括自动刷新会话令牌），以避免在会话到期时服务中断。有关授权的更多信息，请参阅《Amazon S3 API Reference》**中的 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateSession.html)。要了解有关可用区端点 API 操作的更多信息，请参阅[使用 `CreateSession` 对可用区端点 API 操作进行授权](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-create-session.html)。

 如果您不想覆盖现有对象，则可以在 `RenameObject` 请求中添加带有 `‘*’` 值的 `If-None-Match` 条件标头。如果对象名称已经存在，Amazon S3 将返回 `412 Precondition Failed` 错误。有关更多信息，请参阅《Amazon S3 API 参考》**中的 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html)。

 `RenameObject` 是记录到 AWS CloudTrail 的可用区端点 API 操作（对象级或数据面板操作）。可以使用 CloudTrail 来收集有关对目录存储桶中的对象执行的 `RenameObject` 操作的信息。有关更多信息，请参阅[使用 AWS CloudTrail 对目录存储桶进行日志记录](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-one-zone-logging.html)和[目录存储桶的 CloudTrail 日志文件示例](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-log-files.html)。

S3 Express One Zone 是唯一支持 `RenameObject` 的存储类，其定价与 S3 Express One Zone 中的 `PUT`、`COPY`、`POST` 和 `LIST` 请求（每 1000 个请求）相同。有关更多信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。

## 重命名对象
<a name="directory-bucket-rename"></a>

要重命名目录存储桶中的对象，可以使用 Amazon S3 控制台、AWS CLI、AWS SDK、REST API 或适用于 Amazon S3 的 Mountpoint（版本 1.19.0 或更高版本）。

### 使用 S3 控制台
<a name="set-rename--console"></a>

**重命名目录存储桶中的对象**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在导航窗格中，选择**存储桶**，然后选择**目录存储桶**选项卡。导航到包含要重命名的对象的 Amazon S3 目录存储桶。

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

1. 在**操作**菜单中，选择**重命名对象**。

1. 在**新对象名称**框中，输入对象的新名称。
**注意**  
如果您指定与现有对象相同的对象名称，则操作将失败，并且 Amazon S3 会返回 `412 Precondition Failed` 错误。对象键名称长度不得超过 1024 字节。对象名称中包含的前缀计入总长度。

1. 选择**重命名对象**。Amazon S3 随即重命名您的对象。

### 使用 AWS CLI
<a name="set-rename--cli"></a>

这些 `rename-object` 示例显示了如何使用 AWS CLI 来重命名对象。要运行这些命令，请将*用户输入占位符*替换为您自己的信息。

以下示例显示如何通过对源对象的 ETag 进行条件检查来重命名对象。

```
aws s3api rename-object \                                    
    --bucket amzn-s3-demo-bucket--usw2-az1--x-s3 \
    --key new-file.txt \
    --rename-source original-file.txt \
    --source-if-match "\"a1b7c3d2e5f6\""
```

此命令执行以下操作：
+ 将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从 *original-file.txt* 重命名为 *new-file.txt*。
+ 仅当源对象的 ETag 与“*a1b7c3d4e5f6*”匹配时，才执行重命名。

如果 ETag 不匹配，则操作将失败并显示 `412 Precondition Failed` 错误。

以下示例显示如何通过对新的指定对象名称进行条件检查来重命名对象。

```
aws s3api rename-object \
    --bucket amzn-s3-demo-bucket--usw2-az1--x-s3 \
    --key new-file.txt \
    --rename-source amzn-s3-demo-bucket--usw2-az1--x-s3/original-file.txt \
    --destination-if-none-match "\"e5f3g7h8i9j0\""
```

此命令执行以下操作：
+ 将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从 *original-file.txt* 重命名为 *new-file.txt*。
+ 仅当对象存在且对象的 ETag 与“*e5f3g7h8i9j0*”不匹配时，才执行重命名操作。

如果具有新的指定名称和匹配 ETag 的对象已存在，则操作将失败并显示 `412 Precondition Failed` 错误。

### 使用 AWS SDK
<a name="directory-bucket-rename-sdks"></a>

------
#### [ SDK for Java ]

您可以使用适用于 Java 的 AWS SDK 来重命名对象。要使用这些示例，请将*用户输入占位符*替换为您自己的信息

以下示例演示如何使用适用于 Java 的 AWS SDK 来创建 `RenameObjectRequest`

```
String key = "key";
String newKey = "new-key";
String expectedETag = "e5f3g7h8i9j0";
RenameObjectRequest renameRequest = RenameObjectRequest.builder()
    .bucket(amzn-s3-demo-bucket--usw2-az1--x-s3)
    .key(newKey)
    .renameSource(key)
    .destinationIfMatch(e5f3g7h8i9j0)
    .build();
```

此代码将执行以下操作：
+ 创建一个请求，来将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从“*key*”重命名为“*new-key*”。
+ 包括一个条件，即仅当对象的 ETag 与“*e5f3g7h8i9j0*”匹配时，才会进行重命名。
+ 如果 ETag 不匹配或对象不存在，则操作将失败。

以下示例显示如何使用适用于 Java 的 AWS SDK 通过不匹配条件来创建 `RenameObjectRequest`。

```
String key = "key";
String newKey = "new-key";
String noneMatchETag = "e5f3g7h8i9j0";
RenameObjectRequest renameRequest = RenameObjectRequest.builder()
    .bucket(amzn-s3-demo-bucket--usw2-az1--x-s3)
    .key(newKey)
    .renameSource(key)
    .destinationIfNoneMatch(noneMatchETag)
    .build();
```

此代码将执行以下操作：
+ 创建一个请求，来将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从“*key*”重命名为“*new-key*”。
+ 包含一个使用 `.destinationIfNoneMatch(noneMatchETag)` 的条件，该条件可确保只有在目标对象的 ETag 与“*e5f3g7h8i9j0*”不匹配时，才会进行重命名。

如果具有新的指定名称的对象存在且该对象具有指定的 ETag，则操作将失败并显示 `412 Precondition Failed` 错误。

------
#### [ SDK for Python ]

您可以使用适用于 Python 的 SDK 来重命名对象。要使用这些示例，请将*用户输入占位符*替换为您自己的信息。

以下示例演示了如何使用适用于 Python 的 AWS SDK（Boto3）来重命名对象。

```
def basic_rename(bucket, source_key, destination_key):
    try:
        s3.rename_object(
            Bucket=amzn-s3-demo-bucket--usw2-az1--x-s3,
            Key=destination_key,
            RenameSource=f"{source_key}"
        )
        print(f"Successfully renamed {source_key} to {destination_key}")
    except ClientError as e:
        print(f"Error renaming object: {e}")
```

此代码将执行以下操作：
+ 将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从 *source\$1key* 重命名为 *destination\$1key*。
+ 如果对象重命名获得成功，则会打印一条成功消息；如果重命名失败，则会打印一条错误消息。

以下示例演示如何使用适用于 Python 的 AWS SDK（Boto3）通过 `SourceIfMatch` 和 `DestinationIfNoneMatch` 条件来重命名对象。

```
def rename_with_conditions(bucket, source_key, destination_key, source_etag, dest_etag):
    try:
        s3.rename_object(
            Bucket=amzn-s3-demo-bucket--usw2-az1--x-s3,
            Key=destination_key,
            RenameSource=f"{amzn-s3-demo-bucket--usw2-az1--x-s3}/{source_key}",
            SourceIfMatch=source_ETag,
            DestinationIfNoneMatch=dest_ETag
        )
        print(f"Successfully renamed {source_key} to {destination_key} with conditions")
    except ClientError as e:
        print(f"Error renaming object: {e}")
```

此代码将执行以下操作：
+ 执行有条件的重命名操作并应用两个条件：`SourceIfMatch` 和 `DestinationIfNoneMatch`。这些条件的组合可确保对象未被修改，并且不存在具有新的指定名称的对象。
+ 将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从 *source\$1key* 重命名为 *destination\$1key*。
+ 如果对象重命名获得成功，则会打印一条成功消息；如果重命名失败或条件未得到满足，则会打印一条错误消息。

------
#### [ SDK for Rust ]

您可以使用适用于 Rust 的 SDK 来重命名对象。要使用这些示例，请将*用户输入占位符*替换为您自己的信息。

以下示例演示如何使用适用于 Rust 的 SDK 来重命名 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的对象。

```
async fn basic_rename_example(client: &Client) -> Result<(), Box<dyn Error>> {
    let response = client
        .rename_object()
        .bucket(" amzn-s3-demo-bucket--usw2-az1--x-s3")
        .key("new-name.txt")  // New name/path for the object
        .rename_source("old-name.txt")  // Original object name/path
        .send()
        .await?;
    Ok(())
}
```

此代码将执行以下操作：
+ 创建一个请求，来将 *amzn-s3-demo-bucket--usw2-az1--x-s3* 目录存储桶中的一个对象从“*old-name.tx*”重命名为“*new-name.txt*”。
+ 返回用于处理潜在错误的 `Result` 类型。

------

### 使用 REST API
<a name="directory-bucket-rename-api"></a>

 您可以发送 REST 请求来重命名对象。有关更多信息，请参阅《Amazon S3 API 参考》**中的 [https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_RenameObject.html)。

### 使用适用于 Amazon S3 的 Mountpoint
<a name="directory-bucket-rename-api"></a>

 从 1.19.0 版本或更高版本起，适用于 Amazon S3 的 Mountpoint 支持重命名 S3 Express One Zone 中的对象。有关 Mountpoint 的更多信息，请参阅[使用 Mountpoint](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mountpoint.html)。