我见过的使用AWS SDK for Go从S3下载文件的示例如下:
downloader := s3manager.NewDownloader(session, /* other args */)
s3object := &s3.GetObjectInput{
Bucket: aws.String(myBucket),
Key: aws.String(myKey),
}
bytesDownloaded, err := downloader.Download(myFile, s3object)
即,使用存储桶和密钥指定文件。但是如果我已经在S3上拥有该文件的完整URI呢? E.g:
https://s3.us-west-2.amazonaws.com/myBucket/myKey
有没有办法使用SDK直接使用URL指定要下载的文件?
不,存储桶不公开。在SDK中,我还设置了访问密钥和密钥(从示例代码中省略)。
最后,如果根本无法通过SDK执行我所要求的操作,那么这是一个可接受的(虽然不是理想的)答案。
答案 0 :(得分:3)
没有办法做你想做的事。获取私有对象的唯一方法是:
hhtp.Get
(以生成您需要存储桶和密钥的预签名网址)如果你真的想使用我建议你创建一个s3.GetObjectInput
的包装器,它接受URL作为参数,解析它然后创建s3.GetObjectInput
对象。
另外,我不知道你是否可以这样做取决于你的使用案例,但是如果你在某处存放URL并且这就是你想要使用它们的原因,那么你可以考虑使用long来存储预先签名的URL到期时间,然后当您想要获取对象时,您可以使用该URL。
答案 1 :(得分:1)
您可以解析URL以获取存储桶和密钥:
package main
import (
"fmt"
"log"
"net/url"
"strings"
)
func main() {
u, err := url.Parse("https://s3.us-west-2.amazonaws.com/myBucket/myKey/morekey")
if err != nil {
log.Fatal(err)
}
path := strings.SplitN(u.Path, "/", 3)
bucket := path[1]
key := path[2]
fmt.Println(bucket)
fmt.Println(key)
}
答案 2 :(得分:1)
为此创建了新的S3URLtoURI解析器。
func S3URLtoURI(s3Url string) (map[string]string, error) {
m := make(map[string]string)
u, err := url.Parse(s3Url)
if err != nil {
return m, err
}
if u.Scheme == "s3" {
//s3: //bucket/key
m["bucket"] = u.Host
m["key"] = strings.TrimLeft(u.Path, "/")
} else if u.Scheme == "https" {
host := strings.SplitN(u.Host, ".", 2)
if host[0] == "s3" {
// No bucket name in the host;
path := strings.SplitN(u.Path, "/", 3)
m["bucket"] = path[1]
m["key"] = path[2]
} else { //bucket name in host
m["bucket"] = host[0]
m["key"] = strings.TrimLeft(u.Path, "/")
}
}
return m, err
}
答案 3 :(得分:0)
首先,您需要在尝试从S3下载的对象上启用公共访问。您可以通过以下任一方法实现此目的。
现在最后一步是使用go http client来调用预先签名的网址并下载所需的对象。