【问题标题】:Upload a struct or object to S3 bucket using GoLang?使用 GoLang 将结构或对象上传到 S3 存储桶?
【发布时间】:2021-08-26 22:31:52
【问题描述】:

我正在使用 GoLang 中的 AWS S3 开发工具包,上传和下载到各种存储桶。我想知道是否有更简单的方法可以将结构或对象直接上传到存储桶?

我有一个表示事件的结构:

type Event struct {
    ID               string
    ProcessID        string                 
    TxnID            string
    Inputs           map[string]interface{}                      
}

我想上传到 S3 存储桶。但我在文档中找到的代码仅适用于上传字符串。

func Save(client S3Client, T interface{}, key string) bool {
    svc := client.S3clientObject
    input := &s3.PutObjectInput{
        Body: aws.ReadSeekCloser(strings.NewReader("testing this one")),
        Bucket: aws.String(GetS3Bucket()),
        Key: aws.String(GetObjectKey(T, key)),
        Metadata: map[string]*string{
            "metadata1": aws.String("value1"),
            "metadata2": aws.String("value2"),
        },

    }

这成功地将基本文件上传到 S3 存储桶,打开该存储桶时仅显示“正在测试这个”。有没有办法上传到存储桶,以便它上传一个对象而不仅仅是一个字符串值??

感谢任何帮助,因为我是 Go 和 S3 的新手。

编辑

这是我用于 Get 函数的代码:

func GetIt(client S3Client, T interface{}, key string) interface{} {
    svc := client.S3clientObject
    s3Key := GetObjectKey(T, key)
    resp, err := svc.GetObject(&s3.GetObjectInput{
        Bucket: aws.String(GetS3Bucket()),
        Key: aws.String(s3Key),
    })
    if err != nil {
        fmt.Println(err)
        return err
    }    
    result := json.NewDecoder(resp.Body).Decode(&T)
    fmt.Println(result) 
    return json.NewDecoder(resp.Body).Decode(&T)
}
func main() {
    client := b.CreateS3Client()
    event := b.CreateEvent()
    GetIt(client, event, key)
}

【问题讨论】:

    标签: amazon-web-services go amazon-s3


    【解决方案1】:

    将值编码为字节并上传字节。以下是将值编码为 JSON 字节的方法:

    func Save(client S3Client, value interface{}, key string) error {
    
        p, err := json.Marshal(value)
        if err != nil {
            return err
        }
        input := &s3.PutObjectInput{
            Body:   aws.ReadSeekCloser(bytes.NewReader(p)),
            …
        }
        …
    }
    

    使用您要上传的值调用 Save:

    value := &Event{ID: "an id", …}
    err := Save(…, value, …)
    if err != nil {
      // handle error
    }
    

    有很多可能,包括gobxmljsonmsgpack等。最佳编码格式将取决于您的应用程序要求。

    获取对象时逆过程:

    func GetIt(client S3Client, T interface{}, key string) error {
        svc := client.S3clientObject
        resp, err := svc.GetObject(&s3.GetObjectInput{
            Bucket: aws.String(GetS3Bucket()),
            Key: aws.String(key),
        })
        if err != nil {
            return err
        }    
        return json.NewDecoder(resp.Body).Decode(T)
    }
    

    使用指向目标值的指针调用 GetIt:

    var value model.Event
    err := GetIt(client, &value, key)
    if err != nil {
        // handle error
    }
    fmt.Println(value) // prints the decoded value.
    

    【讨论】:

    • 谢谢!如果我尝试从 S3 存储桶下载事件而不是上传,您是否知道如何做相反的事情并解码值?
    • 使用指向目标值的指针调用 Load 会导致“恐慌:运行时错误:无效的内存地址或 nil 指针取消引用”错误
    • 恐慌的代码行是 decode := json.NewDecoder(resp.Body).Decode(value)
    • 我现在收到一条错误消息,提示我的密钥不存在(确实存在)。不知道为什么这是大声笑,但我认为它超出了这个错误的范围
    • 我认为这是因为我将 K​​ey 值传递给了另一个名为 GetObjectKey() 的函数(为了避免混淆,我将其省略了),并且因为输入现在是一个指针,它会弄乱该函数.有没有办法取消引用我在 main 中传递的 &event?
    【解决方案2】:

    此处引用的示例显示 S3 允许您上传任何实现 io.Reader 接口的内容。该示例使用strings.NewReader 语法创建一个io.Reader,该io.Reader 知道如何向调用者提供指定的字符串。您的工作(根据 AWS 此处)是弄清楚如何调整您需要存储到 io.Reader 中的任何内容。

    您可以像这样直接存储 JSON 编码的字节

    package main
    
    import (
        "bytes"
        "encoding/json"
    )
    
    type Event struct {
        ID               string
        ProcessID        string
        TxnID            string
        Inputs           map[string]interface{}
    }
    
    func main() {
        // To prepare the object for writing
        b, err := json.Marshal(event)
        if err != nil {
            return
        }
        // pass this reader into aws.ReadSeekCloser(...)
        reader := bytes.NewReader(b)
    }
    

    【讨论】:

    • 谢谢!如果我尝试从 S3 存储桶下载事件而不是上传,您是否知道如何做相反的事情并解码这些值?
    猜你喜欢
    • 2022-11-23
    • 2017-04-19
    • 2015-09-10
    • 2022-01-07
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多