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

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

direct file upload to Google bucket with REST API

问题

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

func uploadFile(bucket string, fileBytes []byte, destFilePath string) error {
    os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "./credential.json")
    ctx := context.Background()
    client, err := storage.NewClient(ctx)
    if err != nil {
        return fmt.Errorf("storage.NewClient: %v", err)
    }
    defer client.Close()

    ctx, cancel := context.WithTimeout(ctx, time.Second*50)
    defer cancel()
    o := client.Bucket(bucket).Object(destFilePath)
    o = o.If(storage.Conditions{DoesNotExist: true})

    // Upload an object with storage.Writer.
    wc := o.NewWriter(ctx)
    if _, err = wc.Write(fileBytes); err != nil {
        return fmt.Errorf("wc.Write: %v", err)
    }
    if err := wc.Close(); err != nil {
        return fmt.Errorf("Writer.Close: %v", err)
    }
    return nil
}

func main() {
    bucket := "g1-mybucket-001"
    fileBytes := []byte("your file content here")
    destFilePath := "it_poc_test_folder/somefile.txt"
    err := uploadFile(bucket, fileBytes, destFilePath)
    if err != nil {
        fmt.Println(fmt.Errorf("Error uploading file: %v", err))
    } else {
        fmt.Printf("File uploaded to %s.\n", destFilePath)
    }
}

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

英文:

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

func uploadFile(bucket string, uploadFilePath string, destFilePath string) error {
    os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", "./credential.json")
    ctx := context.Background()
    client, err := storage.NewClient(ctx)
    if err != nil {
        return fmt.Errorf("storage.NewClient: %v", err)
    }
    defer client.Close()

    // Open local file.
    f, err := os.Open(uploadFilePath)
    if err != nil {
        return fmt.Errorf("os.Open: %v", err)
    }
    defer f.Close()

    ctx, cancel := context.WithTimeout(ctx, time.Second*50)
    defer cancel()
    o := client.Bucket(bucket).Object(destFilePath)
    o = o.If(storage.Conditions{DoesNotExist: true})
    
    // Upload an object with storage.Writer.
    wc := o.NewWriter(ctx)
    if _, err = io.Copy(wc, f); err != nil {
        return fmt.Errorf("io.Copy: %v", err)
    }
    if err := wc.Close(); err != nil {
        return fmt.Errorf("Writer.Close: %v", err)
    }
    return nil
}

func main() {
    bucket := "g1-mybucket-001"
    targetFilePath := "./somefile.txt"
    destFilePath := "it_poc_test_folder/somefile.txt"
    err := uploadFile(bucket, targetFilePath, destFilePath)
    if err != nil {
        fmt.Println(fmt.Errorf("Error uplolading file: %v", err))
    } else {
        fmt.Printf("%s uploaded to %s.\n", targetFilePath, destFilePath)
    }
}

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

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

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

    // ... 
    r.ParseMultipartForm(10 << 20)
    f, handler, err := r.FormFile("myFile")
    if err != nil {
        // 处理错误
    }
    defer f.Close()
    // ...
}

所以只需将文件上传的 `f` 主体简单地传递给云上传逻辑就像它是一个本地文件一样

// 相同的代码 - 不同的 `f` 来源

// 使用 storage.Writer 上传对象
wc := o.NewWriter(ctx)
if _, err = io.Copy(wc, f); err != nil {
    return fmt.Errorf("io.Copy: %v", err)
}

以上是要翻译的内容。

英文:

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

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

    // ... 
    r.ParseMultipartForm(10 &lt;&lt; 20)
    f, handler, err := r.FormFile(&quot;myFile&quot;)
    if err != nil {
        // handle err
    }
    defer f.Close()
    // ...
}

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

// same code - different `f` source

// Upload an object with storage.Writer.
wc := o.NewWriter(ctx)
if _, err = io.Copy(wc, f); err != nil {
    return fmt.Errorf(&quot;io.Copy: %v&quot;, err)
}

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:

确定