Amazon web services 使用GoLang将结构或对象上载到S3 bucket?

Amazon web services 使用GoLang将结构或对象上载到S3 bucket?,amazon-web-services,go,amazon-s3,Amazon Web Services,Go,Amazon S3,我在GoLang使用AWS S3 SDK,处理各种bucket的上传和下载。我想知道是否有更简单的方法将结构或对象直接上传到bucket 我有一个表示事件的结构: type Event struct { ID string ProcessID string TxnID string Inputs map[string]interface{}

我在GoLang使用AWS S3 SDK,处理各种bucket的上传和下载。我想知道是否有更简单的方法将结构或对象直接上传到bucket

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

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存储桶,打开该存储桶时,它只会显示“testing This one”。有没有一种方法可以上传到bucket,这样它就可以上传一个对象,而不仅仅是一个字符串值

感谢您的帮助,因为我是新手

编辑

这是我用于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)
}

这里引用的示例显示,S3允许您上传实现该接口的任何内容。示例是使用
strings.NewReader
语法创建一个
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允许您上传实现该接口的任何内容。示例是使用
strings.NewReader
语法创建一个
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)
}

将值编码为字节并上载字节。以下是如何将值编码为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
}
有许多可能的编码格式,包括、和等。最佳编码格式将取决于您的应用程序要求

获取对象时,请反转此过程:

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.

将值编码为字节并上载字节。以下是如何将值编码为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
}
有许多可能的编码格式,包括、和等。最佳编码格式将取决于您的应用程序要求

获取对象时,请反转此过程:

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 bucket下载事件而不是上传,您知道如何做相反的事情并解码值吗?使用指向目标值的指针调用Load会导致“panic:runtime error:invalid memory address:invalid memory address or nil pointer dereference”错误代码行panick为decode:=json.NewDecoder(分别为主体)。解码(值)我在这里更新了问题中的代码。@yungcoder我编辑了答案,以便与问题中的新代码保持一致。谢谢!如果我试图从S3存储桶下载事件而不是上传,您是否知道如何做相反的事情并解码值?使用指向目标值的指针调用Load会导致“恐慌:运行时e”错误:无效内存地址或零指针解引用错误代码恐慌行为decode:=json.NewDecoder(resp.Body).decode(value)我在这里更新了问题中的代码。@yungcoder我编辑了答案以与问题中的新代码保持一致。谢谢!如果我尝试从S3 bucket下载事件而不是上传,您是否知道如何做相反的事情并解码值?谢谢!如果我尝试上传,您是否知道如何做相反的事情并解码值您是否正在尝试从S3存储桶下载事件,而不是上传?