最近更新时间:2026-10-15 14:43:39
解冻源对象:对归档/冷归档对象调用 RestoreObject进行解冻,并等待解冻完成。归档存储类型文件1-10 分钟解冻完成,冷归档 1-12 小时解冻完成。
copy 并显式指定 STANDARD:解冻完成后,用 CopyObject 指定目标存储类型为 STANDARD。
验证:HeadObject 确认目标对象 x-kss-storage-class 为 STANDARD。
POST /{ObjectKey}?restore HTTP/1.1
Host: {BucketName}.{endpoint}
Date: {date}
Authorization: {SignatureValue}
<RestoreRequest>
<Days>1</Days> <!-- 归档 1~7;冷归档 1~365 -->
<JobParameters>
<Tier>Expedited</Tier> <!-- 冷归档可选:Expedited/Standard/Bulk;归档不填 -->
</JobParameters>
</RestoreRequest>响应:202(首次受理)/ 200(已解冻完成)/ 409(解冻中重复调用)
RestoreObject接口具体描述参见Restore Object文档。
HEAD /{ObjectKey} HTTP/1.1
Host: {BucketName}.{endpoint}
# 响应头示例:
# x-kss-restore: ongoing-request="false", expiry-date="Sun, 16 Apr 2026 08:12:33 GMT"ongoing-request="true" 解冻中,"false" 已解冻。
HeadObject接口具体描述参见HEAD Object文档。
PUT /{DestinationKey} HTTP/1.1
Host: {DestinationBucket}.{endpoint}
x-kss-copy-source: /{SourceBucket}/{SourceKey}
x-kss-storage-class: STANDARD <!-- 关键:显式指定标准存储 -->
x-kss-metadata-directive: COPYPUT Object Copy默认行为分两种情况:源与目标 Key 相同时,继承源文件的存储类型;源和目标不同 Key 时,继承目标桶的存储类型。接口具体描述参见PUT Object Copy文档。
HeadObject 目标对象,若x-kss-storage-class: STANDARD,则目标对象成功设置存储类型为标准存储。
# 1. 解冻源对象
# 归档:--days 取 1~7;冷归档:--days 取 1~365,--tier 可选 Expedited/Standard/Bulk(默认高优先级)
./ks3util restore ks3://srcBucket/srcKey --days 1
# 2. 复制并显式指定标准存储
./ks3util cp ks3://srcBucket/srcKey ks3://dstBucket/dstKey --storage-class STANDARD
# 3. 验证目标存储类型
./ks3util stat ks3://dstBucket/dstKey使用该功能时,请确保KS3Util工具为 2.18.0 或更高版本。若未指定--storage-class参数,则复制后文件的存储类型与源文件保持一致。
--storage-class 可选值:STANDARD、STANDARD_IA、ARCHIVE。
KS3Util命令行工具具体描述可参考文档:解冻文件(restore)、复制文件(cp)。
/**
* 解冻对象
* 仅归档及更冷存储类型的对象支持解冻操作
*/
public void restoreObject() {
// 初始化 Ks3Client,参见“初始化”文档
Ks3Client ks3Client = initKs3Client();
try {
// 创建 RestoreObjectRequest 对象
RestoreObjectRequest request = new RestoreObjectRequest("bucketName", "objectKey");
// 设置解冻时间,单位:天
// 可设置解冻状态持续时间,归档范围为1-7天,冷归档范围为1-365天。
// 对于已处于解冻状态中的文件,可再次进行解冻操作,重新设置解冻持续时间,新设置的解冻持续时间将以当天为起始时间重新开始计算。
request.setExpirationInDays(1);
// 设置解冻优先级,取值:Expedited 高优先级、Standard 标准、Bulk 批量
// 如果对象存储类型是 ColdArchive 冷归档,则可选 3 种,默认为 Expedited 高优先级
// 如果对象存储类型是 Archive 归档则不支持设置解冻优先级
request.setTier(RestoreTier.EXPEDITED);
// 解冻对象
RestoreObjectResult restoreObjectResult = ks3Client.restoreObject(request);
// 获取对象存储类型:Archive 归档、ColdArchive 冷归档
System.out.println("Storage Class: " + restoreObjectResult.getStorageClass());
// 获取解冻状态,取值:RESTORE:解冻,RESTORING:解冻中,RESTORED:已解冻
// 如果是初次解冻,一般不会立即完成,可以稍后使用 headObject 接口获取解冻状态
System.out.println("RestoreStatus: " + restoreObjectResult.getType());
} catch (Ks3ServiceException e) {
System.out.println("Ks3ServiceException occurred, which means the request was made to KS3, but KS3 returned an error response for some reason.");
System.out.println("Error Message: " + e.getErrorMessage());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
} catch (Ks3ClientException e) {
System.out.println("Ks3ClientException occurred, which means the client encountered an internal error while trying to communicate with KS3.");
System.out.println("Error Message: " + e.getMessage());
} finally {
// 不再使用时,关闭 Ks3Client
ks3Client.shutdown();
}
}/**
* 获取对象解冻状态
*/
public void getObjectRestoreStatus() {
// 初始化 Ks3Client,参见“初始化”文档
Ks3Client ks3Client = initKs3Client();
try {
// 获取对象解冻状态
HeadObjectResult headObjectResult = ks3Client.headObject("bucketName", "objectKey");
// 对解冻中的或已解冻的归档文件进行head请求时,会返回x-kss-restore响应头
// 解冻中的文件会返回x-kss-restore: ongoing-request="true"
// 已解冻的文件会返回x-kss-restore: ongoing-request="false"及解冻过期时间,
// 例如:x-kss-restore: ongoing-request="false", expiry-date="Sun, 16 Apr 2017 08:12:33 GMT"
String restoreHeaderValue = (String) headObjectResult.getObjectMetadata().getMeta(HttpHeaders.XKssRestore.toString());
System.out.println("RestoreStatus: " + restoreHeaderValue);
// 可以使用以下方法获取解冻状态
RestoreStatus restoreStatus = headObjectResult.getObjectMetadata().getRestoreStatus();
if (restoreStatus != null) {
System.out.println("Ongoing: " + restoreStatus.isOngoing());
System.out.println("Expiry Date: " + restoreStatus.getExpiryDate());
}
} catch (Ks3ServiceException e) {
System.out.println("Ks3ServiceException occurred, which means the request was made to KS3, but KS3 returned an error response for some reason.");
System.out.println("Error Message: " + e.getErrorMessage());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
} catch (Ks3ClientException e) {
System.out.println("Ks3ClientException occurred, which means the client encountered an internal error while trying to communicate with KS3.");
System.out.println("Error Message: " + e.getMessage());
} finally {
// 不再使用时,关闭 Ks3Client
ks3Client.shutdown();
}
}// 初始化 Ks3Client,参见“初始化”文档
Ks3Client ks3Client = initKs3Client();
try {
// 创建copy请求,将sourceBucket这个存储空间下的sourceKey这个object复制到destinationBucket这个存储空间下,并命名为destinationObject
CopyObjectRequest request = new CopyObjectRequest("destinationBucket", "destinationObject", "sourceBucket", "sourceKey");
// 设置新文件的ACL
request.setCannedAcl(CannedAccessControlList.Private);
// 或者指定用户的权限
AccessControlList acl = new AccessControlList();
acl.addGrant(new GranteeId("<user-id-1>"), Permission.Read);
acl.addGrant(new GranteeId("<user-id-2>"), Permission.Write);
request.setAccessControlList(acl);
// 设置新文件的存储类型
request.setStorageClass(StorageClass.Standard);
// 设置新文件的元数据
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType("text/plain");
objectMetadata.setUserMeta("key1", "value1");
// 设置新文件的元数据指令,REPLACE 表示替换,COPY 表示保留原有元数据
objectMetadata.setHeader(HttpHeaders.XKssMetadataDirective.toString(), "REPLACE");
// 设置新文件的标签指令,REPLACE 表示替换,COPY 表示保留原有标签
objectMetadata.setHeader(HttpHeaders.XKssTaggingDirective.toString(), "REPLACE");
request.setNewObjectMetadata(objectMetadata);
// 设置新文件的标签
ObjectTagging objectTagging = new ObjectTagging();
objectTagging.addObjectTag("key1", "value1");
request.setObjectTagging(objectTagging);
// 如果目的文件已存在,是否覆盖,true:不覆盖,false:覆盖
request.setForbidOverwrite(true);
ks3Client.copyObject(request);
} catch (Ks3ServiceException e) {
System.out.println("Ks3ServiceException occurred, which means the request was made to KS3, but KS3 returned an error response for some reason.");
System.out.println("Error Message: " + e.getErrorMessage());
System.out.println("Error Code: " + e.getErrorCode());
System.out.println("Request ID: " + e.getRequestId());
} catch (Ks3ClientException e) {
System.out.println("Ks3ClientException occurred, which means the client encountered an internal error while trying to communicate with KS3.");
System.out.println("Error Message: " + e.getMessage());
} finally {
// 不再使用时,关闭 Ks3Client
ks3Client.shutdown();
}Java SDK 在不指定 storage-class 时遵循服务端 CopyObject 默认行为,为避免复制结果仍为归档,务必显式指定 StorageClass.Standard。
SDK具体描述可参考文档:解冻归档文件(Java)、普通复制(Java)。
from ks3.connection import Connection
from ks3.exception import S3ResponseError, KS3ClientError
conn = Connection('<yourAccessKeyId>', '<yourAccessKeySecret>', host='<YOUR_REGION_ENDPOINT>')
src_b = conn.get_bucket('srcBucket')
try:
src_k = src_b.get_key('srcKey')
# 归档:days 取 1~7(归档不支持 tier)
src_k.restore_object(days=1)
# 冷归档:days 取 1~365,tier 可选 Standard/Expedited/Bulk(仅冷归档支持,默认 Standard)
# src_k.restore_object(days=1, tier='Expedited')
except S3ResponseError as e:
print(f'服务端异常: status={e.status}, reason={e.reason}, request_id={e.request_id}')
except KS3ClientError as e:
print(f'客户端异常: {e}')src_k = src_b.get_key('srcKey', validate=True)
# src_k.ongoing_restore 为 True 表示解冻中;为 False 且 expiry_date 有值表示已解冻
print(f'解冻中: {src_k.ongoing_restore}, 过期时间: {src_k.expiry_date}')# 通过 headers 传 x-kss-storage-class
ret = dst_b.copy_key('dstKey', 'srcBucket', 'srcKey',
headers={'x-kss-storage-class': 'STANDARD'})dst_b = conn.get_bucket('dstBucket')
dst_k = dst_b.get_key('dstKey', validate=True)
print(f'目标对象存储类型: {dst_k.storage_class}')Python SDK 指定目标存储类型的方式:在 copy_key 中通过 headers={'x-kss-storage-class': 'STANDARD'} 传入。不指定时默认跟随目标桶存储类型。
SDK具体描述可参考文档:解冻归档文件(Python)、复制文件(Python)。
package main
import (
"fmt"
"github.com/ks3sdklib/aws-sdk-go/aws"
"github.com/ks3sdklib/aws-sdk-go/aws/awsutil"
"github.com/ks3sdklib/aws-sdk-go/aws/credentials"
"github.com/ks3sdklib/aws-sdk-go/service/s3"
)
func main() {
// 创建访问凭证,请将<AccessKeyID>与<SecretAccessKey>替换为实际值
cre := credentials.NewStaticCredentials("<AccessKeyID>", "<SecretAccessKey>", "")
// 创建KS3客户端,更多配置项请查看初始化文档
client := s3.New(&aws.Config{
Credentials: cre, // 访问凭证
Region: "BEIJING", // 访问地域
Endpoint: "ks3-cn-beijing.ksyuncs.com", // 访问域名
})
// 解冻归档文件
resp, err := client.RestoreObject(&s3.RestoreObjectInput{
Bucket: aws.String("srcBucket"), // 存储空间名称,必填
Key: aws.String("srcKey"), // 对象的key,必填
RestoreRequest: &s3.RestoreRequest{
Days: aws.Long(1), // 设置解冻天数,归档范围为1-7天,冷归档范围为1-365天,非必填
//JobParameters: &s3.JobParameters{
// Tier: aws.String(s3.RestoreTierExpedited), // 设置解冻优先级,取值:Expedited 高优先级、Standard 标准、Bulk 批量,非必填
//},
},
})
if err != nil {
panic(err)
}
fmt.Println("结果:\n", awsutil.StringValue(resp))
} // 获取文件元数据信息
resp, err := client.HeadObject(&s3.HeadObjectInput{
Bucket: aws.String("srcBucket"), // 存储空间名称,必填
Key: aws.String("srcKey"), // 对象的key,必填
})
if err != nil {
panic(err)
}
// 对解冻中的或已解冻的归档文件进行head请求时,会返回 X-Amz-Restore 响应头
// 解冻中的文件会返回 X-Amz-Restore: ongoing-request="true"
// 已解冻的文件会返回 X-Amz-Restore: ongoing-request="false"及解冻过期时间,
// 例如:X-Amz-Restore: ongoing-request="false", expiry-date="Sun, 16 Apr 2017 08:12:33 GMT"
fmt.Println("结果:\n", awsutil.StringValue(resp)) // 高级复制
resp, err := client.CopyFile(&s3.CopyFileInput{
SourceBucket: aws.String("srcBucket"), // 源存储空间名称,必填
SourceKey: aws.String("srcKey"), // 源对象的key,必填
Bucket: aws.String("dstBucket"), // 目标存储空间名称,必填
Key: aws.String("dstKey"), // 目标对象的key,必填
StorageClass: aws.String(s3.StorageClassStandard), // 复制后文件的存储类型,必填
})
if err != nil {
panic(err)
}
fmt.Println("结果:\n", awsutil.StringValue(resp)) // 获取文件元数据信息
resp, err := client.HeadObject(&s3.HeadObjectInput{
Bucket: aws.String("dstBucket"), // 存储空间名称,必填
Key: aws.String("dstKey"), // 对象的key,必填
})
if err != nil {
panic(err)
}
fmt.Println("结果:\n", awsutil.StringValue(resp))Go SDK 拷贝在不指定 StorageClass 时存储类型与源对象一致。
SDK具体描述可参考文档:解冻归档文件(Go)、高级复制。
纯净模式
