使用REST API将文件直接上传到Google存储桶。

huangapple go评论126阅读模式
英文:

direct file upload to Google bucket with REST API

问题

根据你提供的代码,你想要将其包装成一个用于文件上传的 REST API。你希望文件直接上传到存储桶,而不是先上传到服务器。要实现这一点,你可以修改代码,使其接受文件的字节流而不是文件路径作为输入。以下是修改后的代码示例:

  1. func uploadFile(bucket string, fileBytes []byte, destFilePath string) error {
  2. os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "./credential.json")
  3. ctx := context.Background()
  4. client, err := storage.NewClient(ctx)
  5. if err != nil {
  6. return fmt.Errorf("storage.NewClient: %v", err)
  7. }
  8. defer client.Close()
  9. ctx, cancel := context.WithTimeout(ctx, time.Second*50)
  10. defer cancel()
  11. o := client.Bucket(bucket).Object(destFilePath)
  12. o = o.If(storage.Conditions{DoesNotExist: true})
  13. // Upload an object with storage.Writer.
  14. wc := o.NewWriter(ctx)
  15. if _, err = wc.Write(fileBytes); err != nil {
  16. return fmt.Errorf("wc.Write: %v", err)
  17. }
  18. if err := wc.Close(); err != nil {
  19. return fmt.Errorf("Writer.Close: %v", err)
  20. }
  21. return nil
  22. }
  23. func main() {
  24. bucket := "g1-mybucket-001"
  25. fileBytes := []byte("your file content here")
  26. destFilePath := "it_poc_test_folder/somefile.txt"
  27. err := uploadFile(bucket, fileBytes, destFilePath)
  28. if err != nil {
  29. fmt.Println(fmt.Errorf("Error uploading file: %v", err))
  30. } else {
  31. fmt.Printf("File uploaded to %s.\n", destFilePath)
  32. }
  33. }

在修改后的代码中,uploadFile 函数接受文件的字节流 fileBytes 作为输入,而不是文件路径。你可以将这个函数用于处理 REST API 请求中的文件上传。

英文:

Following the Go example, I have this code to upload a file to a Google bucket:

  1. func uploadFile(bucket string, uploadFilePath string, destFilePath string) error {
  2. os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "./credential.json")
  3. ctx := context.Background()
  4. client, err := storage.NewClient(ctx)
  5. if err != nil {
  6. return fmt.Errorf("storage.NewClient: %v", err)
  7. }
  8. defer client.Close()
  9. // Open local file.
  10. f, err := os.Open(uploadFilePath)
  11. if err != nil {
  12. return fmt.Errorf("os.Open: %v", err)
  13. }
  14. defer f.Close()
  15. ctx, cancel := context.WithTimeout(ctx, time.Second*50)
  16. defer cancel()
  17. o := client.Bucket(bucket).Object(destFilePath)
  18. o = o.If(storage.Conditions{DoesNotExist: true})
  19. // Upload an object with storage.Writer.
  20. wc := o.NewWriter(ctx)
  21. if _, err = io.Copy(wc, f); err != nil {
  22. return fmt.Errorf("io.Copy: %v", err)
  23. }
  24. if err := wc.Close(); err != nil {
  25. return fmt.Errorf("Writer.Close: %v", err)
  26. }
  27. return nil
  28. }
  29. func main() {
  30. bucket := "g1-mybucket-001"
  31. targetFilePath := "./somefile.txt"
  32. destFilePath := "it_poc_test_folder/somefile.txt"
  33. err := uploadFile(bucket, targetFilePath, destFilePath)
  34. if err != nil {
  35. fmt.Println(fmt.Errorf("Error uplolading file: %v", err))
  36. } else {
  37. fmt.Printf("%s uploaded to %s.\n", targetFilePath, destFilePath)
  38. }
  39. }

Now I plan to wrap it to create a REST API for file upload. I then realize that the code is for upload a local file only. How can I wrap it so that the file would go straight to the bucket, without first uploading it to the server?

答案1

得分: 1

有很多文件上传的示例,主要思路如下:

  1. func uploadFile(w http.ResponseWriter, r *http.Request) {
  2. // ...
  3. r.ParseMultipartForm(10 << 20)
  4. f, handler, err := r.FormFile("myFile")
  5. if err != nil {
  6. // 处理错误
  7. }
  8. defer f.Close()
  9. // ...
  10. }
  11. 所以只需将文件上传的 `f` 主体简单地传递给云上传逻辑就像它是一个本地文件一样
  12. // 相同的代码 - 不同的 `f` 来源
  13. // 使用 storage.Writer 上传对象
  14. wc := o.NewWriter(ctx)
  15. if _, err = io.Copy(wc, f); err != nil {
  16. return fmt.Errorf("io.Copy: %v", err)
  17. }

以上是要翻译的内容。

英文:

There are plenty of file upload examples out there, the gist being:

  1. func uploadFile(w http.ResponseWriter, r *http.Request) {
  2. // ...
  3. r.ParseMultipartForm(10 &lt;&lt; 20)
  4. f, handler, err := r.FormFile(&quot;myFile&quot;)
  5. if err != nil {
  6. // handle err
  7. }
  8. defer f.Close()
  9. // ...
  10. }

So just simply pass the f body of the file upload on to your cloud upload logic as if it were a local file:

  1. // same code - different `f` source
  2. // Upload an object with storage.Writer.
  3. wc := o.NewWriter(ctx)
  4. if _, err = io.Copy(wc, f); err != nil {
  5. return fmt.Errorf(&quot;io.Copy: %v&quot;, err)
  6. }

huangapple
  • 本文由 发表于 2023年3月24日 17:49:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75832132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定