我正在尝试使用Golang和Amazon 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之外,并且如上所述,其他用户将要上传。无论如何,我可以获得相对路径..
最佳答案
在POST到您的API之后,默认情况下,镜像会临时保存在操作系统的temp目录中(不同的操作系统有所不同)。要获取此目录,可以使用例如:
func GetTempLoc(filename string) string {
return strings.TrimRight(os.TempDir(), "/") + "/" + filename
}
在哪里:
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。
我确信您的框架中会有类似的东西。
然后将其用作
file, err := os.Open(GetTempLoc(fileName))
...