使用 Go 和 AWS SDK v2 实现在不同数据源之间复制目录

使用 Go 和 AWS SDK v2 实现在不同数据源之间复制目录

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

type S3Config struct {
    AccessKey string
    SecretKey string
    Endpoint  string
    Region    string
}

func createS3Client(cfg S3Config) *s3.Client {
    customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
        return aws.Endpoint{
            URL: cfg.Endpoint,
        }, nil
    })

    awsCfg, err := config.LoadDefaultConfig(context.TODO(),
        config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(cfg.AccessKey, cfg.SecretKey, "")),
        config.WithEndpointResolverWithOptions(customResolver),
        config.WithRegion(cfg.Region),
    )
    if err != nil {
        log.Fatal(err)
    }

    return s3.NewFromConfig(awsCfg)
}

func copyDirectory(sourceClient *s3.Client, destClient *s3.Client, sourceBucket, destBucket, sourcePrefix, destPrefix string) error {
    // 列出源目录中的所有对象
    paginator := s3.NewListObjectsV2Paginator(sourceClient, &s3.ListObjectsV2Input{
        Bucket: aws.String(sourceBucket),
        Prefix: aws.String(sourcePrefix),
    })

    for paginator.HasMorePages() {
        page, err := paginator.NextPage(context.TODO())
        if err != nil {
            return fmt.Errorf("failed to list objects: %v", err)
        }

        for _, obj := range page.Contents {
            // 构建目标对象的键
            sourceKey := *obj.Key
            destKey := destPrefix + sourceKey[len(sourcePrefix):]

            // 创建复制源的格式化字符串
            copySource := fmt.Sprintf("%s/%s", sourceBucket, sourceKey)

            // 复制对象
            _, err := destClient.CopyObject(context.TODO(), &s3.CopyObjectInput{
                Bucket:     aws.String(destBucket),
                CopySource: aws.String(copySource),
                Key:        aws.String(destKey),
            })
            if err != nil {
                return fmt.Errorf("failed to copy object %s: %v", sourceKey, err)
            }

            fmt.Printf("Copied: %s -> %s\n", sourceKey, destKey)
        }
    }

    return nil
}

func main() {
    // 配置源数据源
    sourceConfig := S3Config{
        AccessKey: "source_access_key",
        SecretKey: "source_secret_key",
        Endpoint:  "source_endpoint",
        Region:    "source_region", // 例如 "us-east-1"
    }

    // 配置目标数据源
    destConfig := S3Config{
        AccessKey: "dest_access_key",
        SecretKey: "dest_secret_key",
        Endpoint:  "dest_endpoint",
        Region:    "dest_region", // 例如 "us-east-1"
    }

    // 创建源和目标 S3 客户端
    sourceClient := createS3Client(sourceConfig)
    destClient := createS3Client(destConfig)

    // 设置源和目标桶及目录
    sourceBucket := "source-bucket"
    destBucket := "dest-bucket"
    sourcePrefix := "test/"
    destPrefix := "test/"

    // 执行目录复制
    err := copyDirectory(sourceClient, destClient, sourceBucket, destBucket, sourcePrefix, destPrefix)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Directory copy completed successfully")
}

这个程序的主要功能:

  1. 定义了 S3Config 结构体来存储 S3 配置信息(AK、SK、Endpoint 等)

  2. createS3Client 函数用于创建 S3 客户端,支持自定义 endpoint

  3. copyDirectory 函数实现目录复制功能:

    • 列出源目录中的所有对象
    • 为每个对象构建目标路径
    • 使用 CopyObject API 复制每个对象
  4. 在 main 函数中:

    • 配置源和目标数据源的信息
    • 创建相应的 S3 客户端
    • 指定源和目标桶及目录
    • 执行复制操作

使用说明:

  1. 首先安装必要的依赖:
go get github.com/aws/aws-sdk-go-v2
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/credentials
go get github.com/aws/aws-sdk-go-v2/service/s3
  1. 在使用时,需要替换以下配置:

    • source_access_key:源数据源的 AccessKey
    • source_secret_key:源数据源的 SecretKey
    • source_endpoint:源数据源的 Endpoint
    • dest_access_key:目标数据源的 AccessKey
    • dest_secret_key:目标数据源的 SecretKey
    • dest_endpoint:目标数据源的 Endpoint
    • source-bucket:源桶名
    • dest-bucket:目标桶名
  2. 程序会将源数据源中指定目录下的所有文件复制到目标数据源的指定目录中,保持相同的目录结构。

注意事项:

  1. 确保两个数据源的认证信息(AK/SK)具有足够的权限
  2. 确保网络连接正常
  3. 对于大文件或大量文件,可能需要考虑添加错误重试机制
  4. 可以根据需要添加进度显示、并发控制等功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值