使用操作系统打开Golang文件上传到s3 [英] Golang file upload to s3 using OS Open

查看:1890
本文介绍了使用操作系统打开Golang文件上传到s3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用Golang和amazon s3 api将图像上传到我的s3帐户。我可以得到想象上传,如果我硬编码直接路径,如

  file,err:= os.Open(/用户/ JohnSmith / Documents / pictures / cars.jpg)
推迟file.Close()
if err!= nil {
fmt.Printf(err opening file:%s,如果我像这样硬编码的文件路径那么图片将是上传到我的s3帐户。但是这种方法并不好,因为我不能直接将图像路径硬编码到我想要上传的所有图像上。我的问题是我怎样才能上传图像,而不必硬编码的路径。这将是一个用户将上传图像的API的一部分,所以我显然不能有一个硬编码的路径。这是我的代码第一个HTML

 < form method =postenctype =multipart / form-dataaction = profile_image > 
< h2>图片上传< / h2>
< p>< input type =filename =fileid =file/> < / p为H.
< p> < input type =submitvalue =Upload Image>< / p>

< / form>

然后这是我的HTTP Post函数方法

< pre $ func UploadProfile(w http.ResponseWriter,r * http.Request){

r.ParseForm()
var resultt string
resultt =Hi

sess,_:= session.NewSession(& aws.Config {
Region:aws.String(us-west-2),
证书:credentials.NewStaticCredentials(aws_access_key_id,aws_secret_access_key,),

$ b})
svc:= s3.New(sess)

文件,err:= os.Open(Users / JohnSmith / Documents / pictures / cars.jpg)
推迟file.Close()
if err!= nil {
fmt.Printf (err打开文件:%s,err)
}



fileInfo,_:= file.Stat()
size:= fileInfo.Size()
buffer:= make([] byte,size)//读取文件内容到缓冲区

file.Read(buffer)
fileBytes:= bytes。 NewReader(buffer)
fileType:= http.DetectContentType(buffer)
path:= file.Name()
params: =& s3.PutObjectInput {
桶:aws.String(my-bucket),
键:aws.String(path),
正文:fileBytes,
ContentLength :aws.Int64(size),
ContentType:aws.String(fileType),
}
resp,err:= svc.PutObject(params)
if err!= nil {
fmt.Printf(bad response:%s,err)
}
fmt.Printf(response%s,awsutil.StringValue(resp))




$ b $ p
$ b

这是我完整的代码,但是当我尝试做一些诸如 (b)>

  file,err:= os.Open(file)
推迟file.Close()
if err!= nil {
fmt.Printf(err打开文件:%s,err)
}

我得到以下错误:

  http:panic serving [:: 1]:55454:runtime错误:无效的内存地址或零指针解引用
goroutine 7 [running]:
err打开文件:打开文件:没有这样的文件或目录net / http。(* conn).serve.func1(0xc420076e80)

我无法使用绝对路径(filepath.Abs​​())文件将在GoPath之外,正如其他用户将会上传。有没有反正我可以得到一个相对路径..

解决方案

POST到您的API后,图像被临时保存在一个操作系统临时目录(不同的操作系统的)是默认的。例如:

  func GetTempLoc(文件名字符串)string {
返回字符串。 TrimRight(os.TempDir(),/)+/+ filename
}

其中:


  • filename是一个header.Filename,即您的POST请求中收到的文件名。在Gin-Gonic框架中,您可以在请求处理程序中获取它:


  if err!= nil {
return,err
}
推迟文件。关闭()

示例: https://github.com/gin-gonic/gin#another-example-upload-file



我相信在你的框架中会有一个模拟的。



然后用它作为

 文件,err:= os.Open(GetTempLoc(fileName) )
...


I am trying to upload an Image to my s3 account using Golang and the amazon s3 api . I can get the imagine uploaded if I hard code the direct path such as

file, err :=  os.Open("/Users/JohnSmith/Documents/pictures/cars.jpg")
    defer file.Close()
    if err != nil {
        fmt.Printf("err opening file: %s", err)
    }

if I hard code the file path like that then the picture will be uploaded to my s3 account . However that approach is not good as I can't obviously hard code the direct image path to every image that I want to upload . My question is how can I upload images without having to Hardcode the path . This will be apart of an API where users will upload images so I clearly can not have a hard coded path . This is my code first the HTML

<form method="post" enctype="multipart/form-data"  action="profile_image">
    <h2>Image Upload</h2>
    <p><input type="file" name="file" id="file"/> </p>
       <p> <input type="submit" value="Upload Image"></p>

</form>

then this is my HTTP Post function method

func UploadProfile(w http.ResponseWriter, r *http.Request) {

    r.ParseForm()
      var resultt string
    resultt = "Hi"

    sess, _ := session.NewSession(&aws.Config{
        Region:      aws.String("us-west-2"),
        Credentials: credentials.NewStaticCredentials(aws_access_key_id,aws_secret_access_key, ""),


    })
    svc := s3.New(sess)

file, err :=  os.Open("Users/JohnSmith/Documents/pictures/cars.jpg")
defer file.Close()
if err != nil {
    fmt.Printf("err opening file: %s", err)
}



fileInfo, _ := file.Stat()
size := fileInfo.Size()
buffer := make([]byte, size) // read file content to buffer

file.Read(buffer)
fileBytes := bytes.NewReader(buffer)
fileType := http.DetectContentType(buffer)
path := file.Name()
params := &s3.PutObjectInput{
    Bucket: aws.String("my-bucket"),
    Key: aws.String(path),
    Body: fileBytes,
    ContentLength: aws.Int64(size),
    ContentType: aws.String(fileType),
}
resp, err := svc.PutObject(params)
if err != nil {
    fmt.Printf("bad response: %s", err)
}
fmt.Printf("response %s", awsutil.StringValue(resp))

}

That is my full code above however when I try to do something such as

file, err :=  os.Open("file")
    defer file.Close()
    if err != nil {
        fmt.Printf("err opening file: %s", err)
    }

I get the following error

http: panic serving [::1]:55454: runtime error: invalid memory address or nil pointer dereference
goroutine 7 [running]:
err opening file: open file: no such file or directorynet/http.(*conn).serve.func1(0xc420076e80)

I can't use absolute path (filepath.Abs()) because some of the files will be outside of the GoPath and as stated other users will be uploading. Is there anyway that I can get a relative path ..

解决方案

After POST to your API, images are temporarily saved in a OS's temp directory (different for different OS's) by default. To get this directory you can use, for example:

func GetTempLoc(filename string) string {
    return strings.TrimRight(os.TempDir(), "/") + "/" + filename
}

Where:

  • filename is a header.Filename, i.e. file name received in your POST request. In Gin-Gonic framework you get it in your request handler as:

file, header, err := c.Request.FormFile("file")
if err != nil {
    return out, err
}
defer file.Close()

Example: https://github.com/gin-gonic/gin#another-example-upload-file.

I'm sure in your framework there will be an analogue.

  • os.TempDir() is a function go give you a temp folder (details: https://golang.org/pkg/os/#TempDir).
  • TrimRight is used to ensure result of os.TempDir is consistent on different OSs

And then you use it as

file, err := os.Open(GetTempLoc(fileName))
...

这篇关于使用操作系统打开Golang文件上传到s3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆