Golang中如何对S3文件进行排序并选择最新的文件

Golang中如何对S3文件进行排序并选择最新的文件 如何对S3中同名的文件进行排序?并选择最新的一个?

1 回复

更多关于Golang中如何对S3文件进行排序并选择最新的文件的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中对S3文件进行排序并选择最新文件,可以使用AWS SDK for Go的ListObjectsV2方法获取文件列表,然后按最后修改时间排序。以下是实现代码:

package main

import (
    "context"
    "fmt"
    "sort"
    "time"

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

type S3File struct {
    Key          string
    LastModified time.Time
}

func getLatestS3File(bucket, prefix string) (string, error) {
    // 加载AWS配置
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        return "", fmt.Errorf("加载配置失败: %v", err)
    }

    // 创建S3客户端
    client := s3.NewFromConfig(cfg)

    // 列出指定前缀的文件
    resp, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{
        Bucket: aws.String(bucket),
        Prefix: aws.String(prefix),
    })
    if err != nil {
        return "", fmt.Errorf("列出对象失败: %v", err)
    }

    // 将文件信息存入切片
    var files []S3File
    for _, obj := range resp.Contents {
        files = append(files, S3File{
            Key:          *obj.Key,
            LastModified: *obj.LastModified,
        })
    }

    // 如果没有找到文件,返回错误
    if len(files) == 0 {
        return "", fmt.Errorf("未找到匹配的文件")
    }

    // 按最后修改时间降序排序
    sort.Slice(files, func(i, j int) bool {
        return files[i].LastModified.After(files[j].LastModified)
    })

    // 返回最新文件的Key
    return files[0].Key, nil
}

func main() {
    bucket := "your-bucket-name"
    prefix := "your-file-prefix/" // 例如: "logs/app-"
    
    latestFile, err := getLatestS3File(bucket, prefix)
    if err != nil {
        fmt.Printf("错误: %v\n", err)
        return
    }
    
    fmt.Printf("最新文件: %s\n", latestFile)
}

如果需要处理同名文件(相同前缀但不同时间戳),可以在文件名中包含时间戳,然后按时间戳排序:

func getLatestFileByTimestamp(bucket, baseName string) (string, error) {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        return "", err
    }

    client := s3.NewFromConfig(cfg)
    
    resp, err := client.ListObjectsV2(context.TODO(), &s3.ListObjectsV2Input{
        Bucket: aws.String(bucket),
        Prefix: aws.String(baseName),
    })
    if err != nil {
        return "", err
    }

    // 假设文件名格式为: baseName-20231225143045.ext
    var files []S3File
    for _, obj := range resp.Contents {
        files = append(files, S3File{
            Key:          *obj.Key,
            LastModified: *obj.LastModified,
        })
    }

    if len(files) == 0 {
        return "", fmt.Errorf("未找到文件")
    }

    // 按最后修改时间排序
    sort.Slice(files, func(i, j int) bool {
        return files[i].LastModified.After(files[j].LastModified)
    })

    return files[0].Key, nil
}

如果需要基于文件名中的时间戳而非S3的LastModified时间,可以解析文件名中的时间戳进行排序:

import (
    "regexp"
    "strconv"
)

func extractTimestamp(filename string) (time.Time, error) {
    // 正则匹配文件名中的时间戳(格式: YYYYMMDDHHMMSS)
    re := regexp.MustCompile(`(\d{14})`)
    matches := re.FindStringSubmatch(filename)
    
    if len(matches) < 2 {
        return time.Time{}, fmt.Errorf("未找到时间戳")
    }
    
    timestamp := matches[1]
    return time.Parse("20060102150405", timestamp)
}

func sortByFilenameTimestamp(files []S3File) []S3File {
    sort.Slice(files, func(i, j int) bool {
        timeI, errI := extractTimestamp(files[i].Key)
        timeJ, errJ := extractTimestamp(files[j].Key)
        
        // 如果解析失败,使用S3的LastModified作为备选
        if errI != nil {
            timeI = files[i].LastModified
        }
        if errJ != nil {
            timeJ = files[j].LastModified
        }
        
        return timeI.After(timeJ)
    })
    
    return files
}

这些代码示例展示了如何根据不同的需求对S3文件进行排序并选择最新文件。

回到顶部