使用围棋 V2
IBM Cloud® Object Storage SDK for Go v2 提供了可充分利用 IBM Cloud Object Storage 的功能。
IBM Cloud Object Storage SDK for Go v2 功能全面,许多特性和功能超出了本指南的范围。 有关类和方法的详细文档,请参阅 Go API 参考文档。 在 GitHub 存储库中可以找到源代码。
最新消息 v2
IBM Cloud Object Storage SDK for Go v2 是基于 AWS SDK v2 架构的现代化版本,带来了重大改进:
- 模块化架构:新命名空间
github.com/IBM/ibm-cos-sdk-go-v2,组织更简洁 - 增强的上下文支持:本机
context.Context支持所有 API 操作,可更好地处理超时和取消问题 - 现代错误处理:结构化的错误类型更易于检查和编程处理
- 支持 Go 模块:为 Go 模块提供一流的语义版本控制支持
对于从 v1 迁移的开发人员,请参阅《 迁移指南 》。
获取 SDK
使用 IBM Cloud Object Storage Go SDK v2 的最简单方法是使用 Go 模块来管理依赖关系。 如果您不熟悉 Go 模块,可以使用《 Go 模块 5 分钟 指南》开始使用。
先决条件
- Go 1.23 或更新版本 - SDK 需要 Go 1.23 或更新版本的最低版本
- 的一个实例 IBM Cloud Object Storage
- 来自 IBM Cloud Identity and Access Management 至少有
Writer权限 - 您正在使用的 IBM Cloud Object Storage 实例的 ID
- 代币收购终端
- 服务端点
这些值可通过 生成 "服务凭证 " 在 IBM Cloud 控制台中找到。
安装 SDK
使用 go get 可检索 SDK 以将其添加到 GOPATH 工作空间,或检索项目的 Go 模块依赖项。 SDK 需要的 Go 最低版本为 1.23。
go get github.com/IBM/ibm-cos-sdk-go-v2/config
go get github.com/IBM/ibm-cos-sdk-go-v2/service/s3
go get github.com/IBM/ibm-cos-sdk-go-v2/credentials/ibmiam
要更新 SDK,请使用 go get -u 获取 SDK 的最新版本:
go get -u github.com/IBM/ibm-cos-sdk-go-v2/config
go get -u github.com/IBM/ibm-cos-sdk-go-v2/service/s3
go get -u github.com/IBM/ibm-cos-sdk-go-v2/credentials/ibmiam
导入包
安装 SDK 后,需要将所需的包导入到 Go 应用程序才可使用 SDK,如以下示例所示:
import (
"context"
"github.com/IBM/ibm-cos-sdk-go-v2/aws"
"github.com/IBM/ibm-cos-sdk-go-v2/config"
"github.com/IBM/ibm-cos-sdk-go-v2/credentials/ibmiam"
"github.com/IBM/ibm-cos-sdk-go-v2/service/s3"
"github.com/IBM/ibm-cos-sdk-go-v2/service/s3/types"
)
SDK 参考资料
核心类
- s3.Client- 主要与以下客户互动 IBM Cloud Object Storage
- s3.NewFromConfig- 根据配置创建新的 S3 客户端
凭证
- ibmiam.NewStaticCredentials- IBM 用于 API 密钥验证的 IAM 凭据提供商
- config.WithCredentialsProvider- 设置证书提供者的配置选项
配置
- config.LoadDefaultConfig- 使用指定选项加载 SDK 配置
- config.WithRegion- 为客户端设置 AWS 区域
- config.WithEndpoint- 设置服务端点 URL
创建客户和采购服务证书
为了连接到 IBM Cloud Object Storage,将通过提供凭证信息(API 密钥和服务实例标识)来创建和配置客户机。 这些值还可以自动从凭证文件或环境变量中获取。
通过创建服务凭证或通过 CLI 可以找到凭证。
使用 IBM IAM 身份验证
下面的示例展示了如何使用 IBM IAM 身份验证和 API 密钥创建客户端:
// IBM COS credentials
apiKey := "<API_KEY>"
serviceInstanceID := "<RESOURCE_INSTANCE_ID>"
authEndpoint := "https://iam.cloud.ibm.com/identity/token"
serviceEndpoint := "https://s3.us-south.cloud-object-storage.appdomain.cloud"
region := "us-south"
// Load configuration with IBM IAM credentials
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithCredentialsProvider(
ibmiam.NewStaticCredentials(authEndpoint, apiKey, serviceInstanceID),
),
config.WithRegion(region),
config.WithEndpoint(serviceEndpoint),
)
if err != nil {
log.Fatalf("Failed to load configuration: %v", err)
}
// Create S3 client
client := s3.NewFromConfig(cfg)
所需变量为
apiKey- 您的 IBM Cloud API 密钥,具有适当的权限serviceInstanceID- IBM Cloud Object Storage 实例的 CRN(云资源名称authEndpoint- IBM IAM 令牌端点(通常为https://iam.cloud.ibm.com/identity/token)serviceEndpoint- IBM Cloud Object Storage 水桶区域的端点 URLregion- 您的水桶所在的地区
代码示例
以下示例假定您已经创建了一个客户端,如上一节所示。
创建存储区
bucketName := "my-new-bucket"
input := &s3.CreateBucketInput{
Bucket: aws.String(bucketName),
}
_, err = client.CreateBucket(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to create bucket: %v", err)
}
fmt.Printf("Bucket '%s' created successfully\n", bucketName)
列出可用的水桶
result, err := client.ListBuckets(context.TODO(), &s3.ListBucketsInput{})
if err != nil {
log.Fatalf("Failed to list buckets: %v", err)
}
fmt.Println("Buckets:")
for _, bucket := range result.Buckets {
fmt.Printf(" - %s (created: %v)\n",
aws.ToString(bucket.Name),
bucket.CreationDate,
)
}
列出带有扩展信息的存储桶
IBM Cloud Object Storage 提供了一种扩展的列表操作,可返回更多的水桶信息:
input := &s3.ListBucketsExtendedInput{
IBMServiceInstanceId: aws.String(serviceInstanceID),
Prefix: aws.String("my-bucket-prefix"),
MaxKeys: aws.Int32(100),
}
result, err := client.ListBucketsExtended(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to list buckets: %v", err)
}
fmt.Println("Extended Bucket Information:")
for _, bucket := range result.Buckets {
fmt.Printf(" Bucket: %s\n", aws.ToString(bucket.Name))
fmt.Printf(" Location: %s\n", aws.ToString(bucket.LocationConstraint))
fmt.Printf(" Created: %v\n", bucket.CreationDate)
}
检索水桶的位置
bucketName := "my-bucket"
result, err := client.GetBucketLocation(context.TODO(), &s3.GetBucketLocationInput{
Bucket: aws.String(bucketName),
})
if err != nil {
log.Fatalf("Failed to get bucket location: %v", err)
}
fmt.Printf("Bucket '%s' is located in: %s\n",
bucketName,
result.LocationConstraint,
)
删除存储区
bucketName := "my-bucket-to-delete"
_, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{
Bucket: aws.String(bucketName),
})
if err != nil {
log.Fatalf("Failed to delete bucket: %v", err)
}
fmt.Printf("Bucket '%s' deleted successfully\n", bucketName)
水桶必须清空后才能删除。
将对象上传到邮筒
bucketName := "my-bucket"
objectKey := "my-object.txt"
content := "Hello, IBM Cloud Object Storage!"
input := &s3.PutObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
Body: strings.NewReader(content),
}
result, err := client.PutObject(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to upload object: %v", err)
}
fmt.Printf("Object '%s' uploaded successfully\n", objectKey)
fmt.Printf("ETag: %s\n", aws.ToString(result.ETag))
从邮筒下载对象
bucketName := "my-bucket"
objectKey := "my-object.txt"
result, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
log.Fatalf("Failed to download object: %v", err)
}
defer result.Body.Close()
// Read the object content
data, err := io.ReadAll(result.Body)
if err != nil {
log.Fatalf("Failed to read object data: %v", err)
}
fmt.Printf("Object '%s' downloaded successfully\n", objectKey)
fmt.Printf("Content-Type: %s\n", aws.ToString(result.ContentType))
fmt.Printf("Content-Length: %d bytes\n", result.ContentLength)
fmt.Printf("Content:\n%s\n", string(data))
列出水桶中的对象
bucketName := "my-bucket"
input := &s3.ListObjectsV2Input{
Bucket: aws.String(bucketName),
MaxKeys: aws.Int32(1000),
}
result, err := client.ListObjectsV2(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to list objects: %v", err)
}
fmt.Printf("Objects in bucket '%s':\n", bucketName)
for _, object := range result.Contents {
fmt.Printf(" - %s (size: %d bytes, modified: %v)\n",
aws.ToString(object.Key),
object.Size,
object.LastModified,
)
}
fmt.Printf("\nTotal objects: %d\n", len(result.Contents))
复制对象
sourceBucket := "source-bucket"
sourceKey := "source-object.txt"
destinationBucket := "destination-bucket"
destinationKey := "destination-object.txt"
// CopySource format: /source-bucket/source-key
copySource := fmt.Sprintf("/%s/%s", sourceBucket, sourceKey)
input := &s3.CopyObjectInput{
Bucket: aws.String(destinationBucket),
Key: aws.String(destinationKey),
CopySource: aws.String(copySource),
}
result, err := client.CopyObject(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to copy object: %v", err)
}
fmt.Printf("Object copied successfully\n")
fmt.Printf("Copy ETag: %s\n", aws.ToString(result.CopyObjectResult.ETag))
删除对象
bucketName := "my-bucket"
objectKey := "object-to-delete.txt"
_, err = client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
log.Fatalf("Failed to delete object: %v", err)
}
fmt.Printf("Object '%s' deleted successfully\n", objectKey)
删除多个对象
bucketName := "my-bucket"
objectsToDelete := []string{
"object1.txt",
"object2.txt",
"object3.txt",
}
// Build delete request
var objects []types.ObjectIdentifier
for _, key := range objectsToDelete {
objects = append(objects, types.ObjectIdentifier{
Key: aws.String(key),
})
}
input := &s3.DeleteObjectsInput{
Bucket: aws.String(bucketName),
Delete: &types.Delete{
Objects: objects,
Quiet: aws.Bool(false),
},
}
result, err := client.DeleteObjects(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to delete objects: %v", err)
}
fmt.Printf("Successfully deleted %d objects\n", len(result.Deleted))
for _, deleted := range result.Deleted {
fmt.Printf(" - %s\n", aws.ToString(deleted.Key))
}
if len(result.Errors) > 0 {
fmt.Printf("\nFailed to delete %d objects:\n", len(result.Errors))
for _, err := range result.Errors {
fmt.Printf(" - %s: %s\n",
aws.ToString(err.Key),
aws.ToString(err.Message),
)
}
}
获取对象元数据(HEAD)
bucketName := "my-bucket"
objectKey := "my-object.txt"
result, err := client.HeadObject(context.TODO(), &s3.HeadObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
log.Fatalf("Failed to get object metadata: %v", err)
}
fmt.Printf("Object Metadata for '%s':\n", objectKey)
fmt.Printf(" Content-Type: %s\n", aws.ToString(result.ContentType))
fmt.Printf(" Content-Length: %d bytes\n", result.ContentLength)
fmt.Printf(" ETag: %s\n", aws.ToString(result.ETag))
fmt.Printf(" Last-Modified: %v\n", result.LastModified)
if len(result.Metadata) > 0 {
fmt.Println(" Custom Metadata:")
for key, value := range result.Metadata {
fmt.Printf(" %s: %s\n", key, value)
}
}
使用分块上传
对于大型对象,多部分上传提高了吞吐量,并能恢复上传。 每部分至少 5 MB(最后一部分除外)。
bucketName := "my-bucket"
objectKey := "large-object.dat"
// Step 1: Initiate multipart upload
createResp, err := client.CreateMultipartUpload(context.TODO(),
&s3.CreateMultipartUploadInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
},
)
if err != nil {
log.Fatalf("Failed to initiate multipart upload: %v", err)
}
uploadID := aws.ToString(createResp.UploadId)
fmt.Printf("Multipart upload initiated with ID: %s\n", uploadID)
// Step 2: Upload parts (minimum 5MB per part except last)
var completedParts []types.CompletedPart
minPartSize := 5 * 1024 * 1024 // 5MB
// Create sample parts
parts := []string{
strings.Repeat("A", minPartSize),
strings.Repeat("B", minPartSize),
}
for i, partData := range parts {
partNumber := int32(i + 1)
uploadResp, err := client.UploadPart(context.TODO(), &s3.UploadPartInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
PartNumber: aws.Int32(partNumber),
UploadId: aws.String(uploadID),
Body: strings.NewReader(partData),
})
if err != nil {
// Abort multipart upload on error
client.AbortMultipartUpload(context.TODO(), &s3.AbortMultipartUploadInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
UploadId: aws.String(uploadID),
})
log.Fatalf("Failed to upload part %d: %v", partNumber, err)
}
completedParts = append(completedParts, types.CompletedPart{
ETag: uploadResp.ETag,
PartNumber: aws.Int32(partNumber),
})
fmt.Printf("Part %d uploaded (ETag: %s)\n", partNumber, aws.ToString(uploadResp.ETag))
}
// Step 3: Complete multipart upload
completeResp, err := client.CompleteMultipartUpload(context.TODO(),
&s3.CompleteMultipartUploadInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
UploadId: aws.String(uploadID),
MultipartUpload: &types.CompletedMultipartUpload{
Parts: completedParts,
},
},
)
if err != nil {
log.Fatalf("Failed to complete multipart upload: %v", err)
}
fmt.Printf("Multipart upload completed successfully\n")
fmt.Printf("Location: %s\n", aws.ToString(completeResp.Location))
fmt.Printf("ETag: %s\n", aws.ToString(completeResp.ETag))
列出多部分上传
bucketName := "my-bucket"
result, err := client.ListMultipartUploads(context.TODO(),
&s3.ListMultipartUploadsInput{
Bucket: aws.String(bucketName),
},
)
if err != nil {
log.Fatalf("Failed to list multipart uploads: %v", err)
}
fmt.Printf("In-progress multipart uploads in bucket '%s':\n", bucketName)
for _, upload := range result.Uploads {
fmt.Printf(" Key: %s\n", aws.ToString(upload.Key))
fmt.Printf(" Upload ID: %s\n", aws.ToString(upload.UploadId))
fmt.Printf(" Initiated: %v\n", upload.Initiated)
}
设置水桶生命周期配置
归档策略可让您在指定时间段后自动将对象过渡到归档存储类别:
bucketName := "my-bucket"
// Configure lifecycle rule to archive objects after 90 days
input := &s3.PutBucketLifecycleConfigurationInput{
Bucket: aws.String(bucketName),
LifecycleConfiguration: &types.BucketLifecycleConfiguration{
Rules: []types.LifecycleRule{
{
ID: aws.String("archive-rule"),
Status: types.ExpirationStatusEnabled,
Filter: &types.LifecycleRuleFilterMemberPrefix{
Value: "documents/",
},
Transitions: []types.Transition{
{
Days: aws.Int32(90),
StorageClass: types.TransitionStorageClassGlacier,
},
},
},
},
},
}
_, err = client.PutBucketLifecycleConfiguration(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to set lifecycle configuration: %v", err)
}
fmt.Printf("Lifecycle configuration set for bucket '%s'\n", bucketName)
获取水桶生命周期配置
bucketName := "my-bucket"
result, err := client.GetBucketLifecycleConfiguration(context.TODO(),
&s3.GetBucketLifecycleConfigurationInput{
Bucket: aws.String(bucketName),
},
)
if err != nil {
log.Fatalf("Failed to get lifecycle configuration: %v", err)
}
fmt.Printf("Lifecycle rules for bucket '%s':\n", bucketName)
for _, rule := range result.Rules {
fmt.Printf(" Rule ID: %s\n", aws.ToString(rule.ID))
fmt.Printf(" Status: %s\n", rule.Status)
for _, transition := range rule.Transitions {
fmt.Printf(" Transition to %s after %d days\n",
transition.StorageClass,
aws.ToInt32(transition.Days),
)
}
}
启用水桶版本控制
bucketName := "my-bucket"
// Enable versioning
_, err = client.PutBucketVersioning(context.TODO(), &s3.PutBucketVersioningInput{
Bucket: aws.String(bucketName),
VersioningConfiguration: &types.VersioningConfiguration{
Status: types.BucketVersioningStatusEnabled,
},
})
if err != nil {
log.Fatalf("Failed to enable versioning: %v", err)
}
fmt.Printf("Versioning enabled for bucket '%s'\n", bucketName)
列出对象版本
bucketName := "my-bucket"
result, err := client.ListObjectVersions(context.TODO(),
&s3.ListObjectVersionsInput{
Bucket: aws.String(bucketName),
},
)
if err != nil {
log.Fatalf("Failed to list object versions: %v", err)
}
fmt.Printf("Object versions in bucket '%s':\n", bucketName)
for _, version := range result.Versions {
fmt.Printf(" Key: %s\n", aws.ToString(version.Key))
fmt.Printf(" Version ID: %s\n", aws.ToString(version.VersionId))
fmt.Printf(" Is Latest: %t\n", aws.ToBool(version.IsLatest))
fmt.Printf(" Last Modified: %v\n", version.LastModified)
}
设置 CORS 配置
bucketName := "my-bucket"
// Set CORS configuration
input := &s3.PutBucketCorsInput{
Bucket: aws.String(bucketName),
CORSConfiguration: &types.CORSConfiguration{
CORSRules: []types.CORSRule{
{
AllowedHeaders: []string{"*"},
AllowedMethods: []string{"GET", "PUT", "POST", "DELETE"},
AllowedOrigins: []string{"https://example.com"},
ExposeHeaders: []string{"ETag"},
MaxAgeSeconds: aws.Int32(3000),
},
},
},
}
_, err = client.PutBucketCors(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to set CORS configuration: %v", err)
}
fmt.Printf("CORS configuration set for bucket '%s'\n", bucketName)
设置对象标记
bucketName := "my-bucket"
objectKey := "my-object.txt"
// Set object tags
input := &s3.PutObjectTaggingInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
Tagging: &types.Tagging{
TagSet: []types.Tag{
{
Key: aws.String("Department"),
Value: aws.String("Finance"),
},
{
Key: aws.String("Project"),
Value: aws.String("Q4-2024"),
},
{
Key: aws.String("Classification"),
Value: aws.String("Confidential"),
},
},
},
}
_, err = client.PutObjectTagging(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to set object tags: %v", err)
}
fmt.Printf("Tags set for object '%s'\n", objectKey)
获取对象标记
bucketName := "my-bucket"
objectKey := "my-object.txt"
result, err := client.GetObjectTagging(context.TODO(), &s3.GetObjectTaggingInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
log.Fatalf("Failed to get object tags: %v", err)
}
fmt.Printf("Tags for object '%s':\n", objectKey)
for _, tag := range result.TagSet {
fmt.Printf(" %s: %s\n", aws.ToString(tag.Key), aws.ToString(tag.Value))
}
恢复存档对象
必须先还原存档存储类中的对象,然后才能访问它们:
bucketName := "my-bucket"
objectKey := "archived-object.txt"
// Restore object with accelerated retrieval (2 hours)
input := &s3.RestoreObjectInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
RestoreRequest: &types.RestoreRequest{
Days: aws.Int32(7), // Number of days to keep restored copy
GlacierJobParameters: &types.GlacierJobParameters{
Tier: types.TierAccelerated, // Accelerated (2 hours) or Standard (12 hours)
},
},
}
_, err = client.RestoreObject(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to restore object: %v", err)
}
fmt.Printf("Restore request submitted for object '%s'\n", objectKey)
fmt.Println("The object will be available for download in approximately 2 hours")
IBM Cloud Object Storage 支持加速存档,还原时间为 2 小时或 12 小时,具体取决于所选级别。
设置水桶保护配置
IBM Cloud Object Storage 支持不可变 Object Storage,以防止对象被修改或删除:
bucketName := "my-protected-bucket"
// Set protection configuration with default retention period
input := &s3.PutBucketProtectionConfigurationInput{
Bucket: aws.String(bucketName),
ProtectionConfiguration: &types.ProtectionConfiguration{
Status: types.BucketProtectionStatusRetention,
MinimumRetention: &types.BucketProtectionMinimumRetention{Days: aws.Int32(90)},
MaximumRetention: &types.BucketProtectionMaximumRetention{Days: aws.Int32(365)},
DefaultRetention: &types.BucketProtectionDefaultRetention{Days: aws.Int32(120)},
EnablePermanentRetention: aws.Bool(false),
},
}
_, err = client.PutBucketProtectionConfiguration(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to set protection configuration: %v", err)
}
fmt.Printf("Protection configuration set for bucket '%s'\n", bucketName)
fmt.Println("Objects will be protected with a default retention of 120 days")
获取水桶保护配置
bucketName := "my-protected-bucket"
result, err := client.GetBucketProtectionConfiguration(context.TODO(),
&s3.GetBucketProtectionConfigurationInput{
Bucket: aws.String(bucketName),
},
)
if err != nil {
log.Fatalf("Failed to get protection configuration: %v", err)
}
fmt.Printf("Protection configuration for bucket '%s':\n", bucketName)
fmt.Printf(" Status: %s\n", result.ProtectionConfiguration.Status)
fmt.Printf(" Minimum Retention: %d days\n",
aws.ToInt32(result.ProtectionConfiguration.MinimumRetention.Days))
fmt.Printf(" Maximum Retention: %d days\n",
aws.ToInt32(result.ProtectionConfiguration.MaximumRetention.Days))
fmt.Printf(" Default Retention: %d days\n",
aws.ToInt32(result.ProtectionConfiguration.DefaultRetention.Days))
为对象添加法律保留
无论保留期限长短,法律保留都会阻止删除或修改对象:
bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"
legalHoldID := "legal-case-2024-001"
// Add legal hold to the object
_, err = client.AddLegalHold(context.TODO(), &s3.AddLegalHoldInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
RetentionLegalHoldId: aws.String(legalHoldID),
})
if err != nil {
log.Fatalf("Failed to add legal hold: %v", err)
}
fmt.Printf("Legal hold '%s' added to object '%s'\n", legalHoldID, objectKey)
fmt.Println("The object cannot be deleted or modified until the legal hold is removed")
水桶必须启用对象锁,才能使用合法保持。
列出对象的合法持有状态
bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"
// List legal holds
result, err := client.ListLegalHolds(context.TODO(), &s3.ListLegalHoldsInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
log.Fatalf("Failed to list legal holds: %v", err)
}
fmt.Printf("Legal holds on object '%s':\n", objectKey)
if len(result.LegalHolds) == 0 {
fmt.Println(" No legal holds")
} else {
for _, hold := range result.LegalHolds {
fmt.Printf(" - ID: %s\n", aws.ToString(hold.ID))
fmt.Printf(" Date: %v\n", hold.Date)
}
}
从对象中删除合法持有
bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"
legalHoldID := "legal-case-2024-001"
// Delete legal hold
_, err = client.DeleteLegalHold(context.TODO(), &s3.DeleteLegalHoldInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
RetentionLegalHoldId: aws.String(legalHoldID),
})
if err != nil {
log.Fatalf("Failed to delete legal hold: %v", err)
}
fmt.Printf("Legal hold '%s' removed from object '%s'\n", legalHoldID, objectKey)
设置对象保留时间
bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"
// Set retention until a specific date
retainUntilDate := time.Now().AddDate(0, 6, 0) // 6 months from now
input := &s3.PutObjectRetentionInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
Retention: &types.ObjectLockRetention{
Mode: types.ObjectLockRetentionModeCompliance,
RetainUntilDate: aws.Time(retainUntilDate),
},
}
_, err = client.PutObjectRetention(context.TODO(), input)
if err != nil {
log.Fatalf("Failed to set object retention: %v", err)
}
fmt.Printf("Retention set for object '%s' until %v\n", objectKey, retainUntilDate)
获取对象保留
bucketName := "my-protected-bucket"
objectKey := "important-document.pdf"
result, err := client.GetObjectRetention(context.TODO(), &s3.GetObjectRetentionInput{
Bucket: aws.String(bucketName),
Key: aws.String(objectKey),
})
if err != nil {
log.Fatalf("Failed to get object retention: %v", err)
}
fmt.Printf("Retention for object '%s':\n", objectKey)
fmt.Printf(" Mode: %s\n", result.Retention.Mode)
fmt.Printf(" Retain Until: %v\n", result.Retention.RetainUntilDate)
后续步骤
- 查看 Go API 参考文档,了解所有可用方法和类型的详细信息
- 访问 GitHub 软件库,查看更多示例和源代码
- 如果您是从以下版本升级,请阅读 迁移指南 v1
- 查看 IBM Cloud Object Storage 文档,了解特定服务的功能和最佳实践
- 寻求帮助和支持:
- 在 Stack Overflow 上提问,标签为
ibm和object-storage - 在 GitHub
- 联系 IBM Cloud 支持
- 在 Stack Overflow 上提问,标签为