版本控制

通过媒体存储提供的版本控制,您可以在一个桶中保留多个对象版本。例如,image.jpg(版本1)和image.jpg(版本2)。如果您希望防止自己意外覆盖和删除版本,或存档对象,以便您可以检索早期版本的对象,您可以开启版本控制功能。

您必须在您的存储桶上显式启用版本控制。默认情况下,版本控制处于禁用状态。无论您是否已启用版本控制,您的存储桶中的每个对象都具有版本 ID。如果未启用版本控制,则版本 ID 值被设置为空。如果已启用版本控制,则对象会被指定唯一版本 ID 值。在存储桶上启用版本控制时,该存储桶中的现有对象(如果有)不会发生更改:版本ID(空)、内容和权限保持为相同。

您可以使用 versioningConfiguration 接口开启版本控制,以下代码展示如何开启版本控制:

String bucketName = "<your-bucket-name>";
BucketVersioningConfiguration versioningConfiguration = new
        BucketVersioningConfiguration();
//启用版本控制
versioningConfiguration.setStatus(BucketVersioningConfiguration.ENABLED);
SetBucketVersioningConfigurationRequest request = new
        SetBucketVersioningConfigurationRequest(bucketName,versioningConfiguration);
s3.setBucketVersioningConfiguration(request);

在开启版本控制功能后,上传同名对象将不再删除旧对象,而是添加一个新的对象。普通的删除操作也不会将对象彻底删除,而是添加一个 Delete Marker 作为标识。容器开启版本控制功能之后,无法再关闭该功能,只能暂停。

以下代码展示如何暂停版本控制:

BucketVersioningConfiguration versioningConfiguration = new
        BucketVersioningConfiguration();
//暂停版本控制
versioningConfiguration.setStatus(BucketVersioningConfiguration.SUSPENDED);
SetBucketVersioningConfigurationRequest request = new
SetBucketVersioningConfigurationRequest(bucketName,versioningConfiguration);
s3.setBucketVersioningConfiguration(request);

获取指定版本对象

您可以通过 GetObject 在 GetObjectRequest 中指定版本ID获取指定版本对象:

//获取指定版本对象时需要指定其版本号
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectKey, versionId);
S3Object s3Object= s3.getObject(getObjectRequest);

列举对象版本

如果桶开启了版本控制,您可以使用 listVersions 接口列举对象的版本,每次list操作最多返回1000个分片上传事件,简单列举对象版本代码如下:

String bucketName = "<your-bucket-name>";
ListVersionsRequest listVersionsRequest = new ListVersionsRequest();
listVersionsRequest.withBucketName(bucketName);
versionListing = s3.listVersions(listVersionsRequest);
for (S3VersionSummary s3VersionSummary: versionListing.getVersionSummaries()) {
    System.out.println(s3VersionSummary.getKey());
    System.out.println(s3VersionSummary.getVersionId());
}

如果 list 大于1000,则返回的结果中 isTruncated 为true,通过返回的 NextKeyMarker 和 NextUploadIdMarker 标记可以作为下次读取的起点。列举所有对象版本示例代码如下:

String bucketName = "<your-bucket-name>";
String nextMarker;
String nextVersionIdMarker;
VersionListing versionListing;
do {
    ListVersionsRequest listVersionsRequest = new ListVersionsRequest();
    listVersionsRequest.withBucketName(bucketName).withKeyMarker(nextMarker).withVersionIdMarker(nextVersionIdMarker);
    versionListing = s3.listVersions(listVersionsRequest);
    for (S3VersionSummary s3VersionSummary: versionListing.getVersionSummaries()) {
       System.out.println(s3VersionSummary.getKey());
       System.out.println(s3VersionSummary.getVersionId());
    }
    nextMarker = versionListing.getNextKeyMarker();
    nextVersionIdMarker = versionListing.getNextVersionIdMarker();
} while (objects.isTruncated());

删除对象版本

如果桶开启了版本控制,您可以使用 deleteVersion 接口删除对象的版本,以下代码展示如何删除单个对象版本:

String bucketName = "<your-bucket-name>";
String objectKey = "<your-object-key>";
String versionID = "<your-object-versionID>";
s3.deleteVersion(bucketName, objectKey, versionID);

默认情况下,如果开启了版本控制,使用 deleteObject 删除对象不会将该对象彻底删除,而是添加一个 Delete Marker 作为标识。如果您确定不再需要某个对象,则需要删除该对象的所有版本,才可以将其彻底删除。对象的版本号可以通过 listVersions 接口获取。您可以通过 deleteVersion 接口删除单个对象版本,也可以通过 deleteObjects 接口在 KeyVersion 中指定 versionID 的方式删除多个对象版本,示例代码如下:

DeleteObjectsRequest deleteObjectRequest = new DeleteObjectsRequest(bucketName);
List<KeyVersion> list = new ArrayList<KeyVersion>();
//在开启多版本功能后,可以在KeyVersion中携带verion id,删除指定版本的对象
KeyVersion key1 = new KeyVersion(objectKey1, versionId1);
KeyVersion key2 = new KeyVersion(objectKey2, versionId12);
list.add(key1);
list.add(key2);
deleteObjectRequest.setKeys(list);
//true是简单模式,false是详细模式
deleteObjectRequest.setQuiet(true);
DeleteObjectsResult result = s3.deleteObjects(deleteObjectRequest);