使用操作系统打开Golang文件上传到s3

时间:2016-12-17 03:53:31

标签: file-upload go amazon-s3

我正在尝试使用Golang和亚马逊s3 api将图片上传到我的s3帐户。如果我硬编码直接路径,如

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

如果我像这样硬编码文件路径,那么图片将被上传到我的s3帐户。然而,这种方法并不好,因为我无法将直接图像路径硬编码到我想要上传的每个图像。我的问题是如何上传图像而无需硬编码路径。这将是用户将上传图像的API的一部分,因此我显然不能拥有硬编码路径。这是我的代码首先是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>

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

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))

}

这是我上面的完整代码,但是当我尝试做

这样的事情时
file, err :=  os.Open("file")
    defer file.Close()
    if err != nil {
        fmt.Printf("err opening file: %s", err)
    }

我收到以下错误

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)

我无法使用绝对路径(filepath.Abs​​()),因为某些文件将位于GoPath之外,并且正如其他用户将要上传的那样。无论如何,我可以得到相对的路径..

1 个答案:

答案 0 :(得分:2)

在POST到您的API之后,默认情况下,图像会临时保存在操作系统的临时目录中(不同的操作系统不同)。要获取此目录,您可以使用,例如:

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

其中:

  • filename是header.Filename,即POST请求中收到的文件名。在Gin-Gonic框架中,您可以在请求处理程序中获取它:
file, header, err := c.Request.FormFile("file")
if err != nil {
    return out, err
}
defer file.Close()

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

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

  • os.TempDir()是一个函数go给你一个临时文件夹(详情:https://golang.org/pkg/os/#TempDir)。
  • TrimRight用于确保os.TempDir的结果在不同的操作系统上是一致的

然后你用它作为

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