重命名文件以满足命名规范

OSS数据迁移或重组过程中,您可以通过重命名文件确保命名一致性和结构准确性。

使用场景

  • 命名规范实施:实施新的文件命名规范时,需要重命名现有对象以提高数据管理效率和一致性。

  • 数据迁移和重组:在组织架构调整、系统迁移或应用程序升级时,可能需要重命名和重组OSS中的数据。

  • 存储布局优化:为了改善数据检索性能和组织结构,有时需要重命名对象以优化存储布局和虚拟目录结构。

注意事项

  • Object一旦被创建,其内容和名称便不可更改。因此,与传统的文件系统不同,在OSS中不能直接通过修改对象的名称来实现文件的重命名。在OSS 的同一Bucket 中,重命名Object需通过CopyObject接口拷贝源Object至目标Object,再通过DeleteObject接口删除源Object。

  • 重命名低频、归档、冷归档或深度冷归档存储类型的Object且未满规定时长,会产生存储不足规定时长的容量费用

  • 已开启版本控制Bucket,仅在历史版本设为隐藏后才能重命名Object。重命名后,原有的Object会增加删除标记。

  • 批量重命名文件时,先列出待更改文件名称,逐个复制并验证新文件是否正确生成,确认无误后再删除原文件,确保数据完整性和安全。

操作步骤

使用OSS控制台

重要

OSS控制台不支持重命名1 GB以上的Object。如需重命名1GB以上的Object,请使用SDK、ossutil、REST API。

  1. 登录OSS管理控制台

  2. 单击Bucket 列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,选择文件管理 > 文件列表,将鼠标指针悬停在目标Object上,然后单击图标edit,对Object进行重命名。重命名时,Object名称需包含后缀。

使用阿里云SDK

例如,将examplebucket中的srcobject.txt重命名为destobject.txt。配置示例如下:

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称。
        String bucketName = "examplebucket";
        // 填写源Object的完整路径,完整路径中不能包含Bucket名称。
        String sourceKey = "srcobject.txt";
        // 填写目标Object的完整路径。Object完整路径中不能包含Bucket名称。
        String destinationKey = "destobject.txt";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";

        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // 将examplebucket下的srcobject.txt拷贝至同一Bucket下的destobject.txt。
            ossClient.copyObject(bucketName, sourceKey, bucketName, destinationKey);

            // 删除srcobject.txt。
            ossClient.deleteObject(bucketName, sourceKey);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
const OSS = require('ali-oss');
const client = new OSS({
  // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  region: 'oss-cn-hangzhou',
  // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  authorizationV4: true,
  // 填写Bucket名称。
  bucket: 'examplebucket',
})

async function renameObject() {
  try {
    // 将srcobject.txt拷贝至同一Bucket下的destobject.txt。
    const r = await client.copy('destobject.txt', 'srcobject.txt');
    console.log('拷贝成功', r);
    // 删除srcobject.txt。
    const deleteResult = await client.delete('srcobject.txt');
    console.log(deleteResult);
  } catch (e) {
    console.log(e);
  }
}

renameObject();
// 填写Bucket名称。
String bucketName = "examplebucket";
// 填写不包含Bucket名称在内源Object的完整路径,例如srcobject.txt。
String sourceObjectKey = "srcobject.txt";
// 填写不包含Bucket名称在内目标Object的完整路径,例如destobject.txt。
String objectKey = "destobject.txt";
try {
    CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, sourceObjectKey, bucketName, objectKey);
    oss.copyObject(copyObjectRequest);
    // 删除srcobject.txt。
    DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(bucketName, sourceObjectKey);
    oss.deleteObject(deleteObjectRequest);
} catch (ClientException e) {
    // 客户端异常,例如网络异常等。
    e.printStackTrace();
} catch (ServiceException e) {
    // 服务端异常。
    Log.e("RequestId", e.getRequestId());
    Log.e("ErrorCode", e.getErrorCode());
    Log.e("HostId", e.getHostId());
    Log.e("RawMessage", e.getRawMessage());
}
// 填写Bucket名称。
NSString *bucketName = @"examplebucket";
// 填写不包含Bucket名称在内源Object的完整路径,例如srcobject.txt。
NSString *sourceObjectKey = @"sourceObjectKey";
// 填写不包含Bucket名称在内目标Object的完整路径,例如destobject.txt。
NSString *objectKey = @"destobject.txt";
[[[OSSTask taskWithResult:nil] continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
    // 将srcobject.txt拷贝至同一Bucket下的destobject.txt。
    OSSCopyObjectRequest *copyRequest = [OSSCopyObjectRequest new];
    copyRequest.bucketName = bucketName;
    copyRequest.sourceBucketName = bucketName;
    copyRequest.sourceObjectKey = sourceObjectKey;
    copyRequest.objectKey = objectKey;
    OSSTask *copyTask = [client copyObject:copyRequest];
    [copyTask waitUntilFinished];
    if (copyTask.error) {
        return copyTask;
    }
    // 删除srcobject.txt。
    OSSDeleteObjectRequest *deleteObject = [OSSDeleteObjectRequest new];
    deleteObject.bucketName = bucketName;
    deleteObject.objectKey = sourceObjectKey;
    OSSTask *deleteTask = [client deleteObject:deleteObject];
    [deleteTask waitUntilFinished];
    if (deleteTask.error) {
        return deleteTask;
    }
    return nil;
}] continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
    if (task.error) {
        NSLog(@"rename fail! error: %@", task.error);
    } else {
        NSLog(@"rename success!");
    }
    return nil;
}];
import argparse
import alibabacloud_oss_v2 as oss

# 创建命令行参数解析器
parser = argparse.ArgumentParser(description="copy object sample")

# 添加命令行参数 --region,表示存储空间所在的区域,必需参数
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令行参数 --bucket,表示目标存储空间的名称,必需参数
parser.add_argument('--bucket', help='The name of the destination bucket.', required=True)
# 添加命令行参数 --endpoint,表示其他服务可用来访问OSS的域名,非必需参数
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令行参数 --key,表示目标对象的名称,必需参数
parser.add_argument('--key', help='The name of the destination object.', required=True)
# 添加命令行参数 --source_key,表示源对象的名称,必需参数
parser.add_argument('--source_key', help='The name of the source object.', required=True)
# 添加命令行参数 --source_bucket,表示源存储空间的名称,必需参数
parser.add_argument('--source_bucket', help='The name of the source bucket.', required=True)

def main():
    # 解析命令行参数
    args = parser.parse_args()

    # 从环境变量中加载凭证信息,用于身份验证
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 加载SDK的默认配置,并设置凭证提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider

    # 设置配置中的区域信息
    cfg.region = args.region

    # 如果提供了endpoint参数,则设置配置中的endpoint
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用配置好的信息创建OSS客户端
    client = oss.Client(cfg)

    # 执行复制对象的请求
    result = client.copy_object(oss.CopyObjectRequest(
        bucket=args.bucket,  # 指定目标存储空间名称
        key=args.key,  # 指定目标对象键名
        source_key=args.source_key,  # 指定源对象键名
        source_bucket=args.source_bucket,  # 指定源存储空间名称
    ))

    # 输出复制对象的结果信息
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' version id: {result.version_id},'
          f' hash crc64: {result.hash_crc64},'
          f' source version id: {result.source_version_id},'
          f' server side encryption: {result.server_side_encryption},'
          f' server side data encryption: {result.server_side_data_encryption},'
          f' last modified: {result.last_modified},'
          f' etag: {result.etag},'
    )

# 当此脚本被直接运行时,调用main函数
if __name__ == "__main__":
    main()  # 脚本入口,当文件被直接运行时调用main函数
<?php

// 引入自动加载文件,确保依赖库能够正确加载
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定义命令行参数的描述信息
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地域(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 访问域名(可选)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // 目标Bucket名称(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 目标对象名称(必填)
    "src-bucket" => ['help' => 'The name of the source bucket', 'required' => False], // 源Bucket名称(可选)
    "src-key" => ['help' => 'The name of the source object', 'required' => True], // 源对象名称(必填)
];

// 将参数描述转换为getopt所需的长选项格式
// 每个参数后面加上":"表示该参数需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令行参数
$options = getopt("", $longopts);

// 验证必填参数是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 获取参数的帮助信息
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填参数缺失,则退出程序
    }
}

// 从解析的参数中提取值
$region = $options["region"]; // Bucket所在的地域
$bucket = $options["bucket"]; // 目标Bucket名称
$key = $options["key"];       // 目标对象名称
$srcKey = $options["src-key"]; // 源对象名称

// 加载环境变量中的凭证信息
// 使用EnvironmentVariableCredentialsProvider从环境变量中读取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 设置凭证提供者
$cfg->setRegion($region); // 设置Bucket所在的地域
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了访问域名,则设置endpoint
}

// 创建OSS客户端实例
$client = new Oss\Client($cfg);

// 创建CopyObjectRequest对象,用于复制对象
$request = new Oss\Models\CopyObjectRequest(
            bucket: $bucket,
            key: $key,
            sourceKey: $srcKey,
            sourceBucket: $bucket);

if (!empty($options["src-bucket"])) {
    $request->sourceBucket = $options["src-bucket"]; // 如果提供了源Bucket名称,则设置sourceBucket
}
$request->sourceKey = $srcKey; // 设置源对象名称

// 执行复制对象操作
$result = $client->copyObject($request);

// 打印复制结果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP状态码,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL     // 请求ID,用于调试或追踪请求
);

关于其他SDK的重命名Object的代码示例,请参见SDK简介

使用图形化管理工具ossbrowser

ossbrowser支持Bucket级别的操作与控制台支持的操作类似,请按照ossbrowser界面指引完成重命名文件的操作。关于如何使用ossbrowser,请参见ossbrowser 2.0常用操作

使用命令行工具ossutil

例如,将examplebucket1中的examplefile.txt重命名为example.txt。配置示例如下:

ossutil cp oss://examplebucket1/examplefile.txt oss://examplebucket1/example.txt 
ossutil rm oss://examplebucket1/examplefile.txt

关于使用ossutil重命名Object的具体步骤,请参见cp(拷贝文件)rm(删除)

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见CopyObjectDeleteObject

相关文档

  • 下载文件时建议您通过预签名URL或文件元数据来实现重命名文件。避免造成额外的费用和导致依赖于原始文件名的应用程序出现错误。具体操作,请参见设置OSS文件下载时的文件名

  • 重命名目录