You need to enable JavaScript to run this app.
导航

禁止覆盖同名文件(Go SDK)

最近更新时间2024.02.04 18:31:09

首次发布时间2023.11.29 14:13:22

本文介绍如何在 Go SDK 中通过设置请求头 x-tos-forbid-overwrite 在上传、拷贝文件及分片上传等场景中禁止覆盖同名文件。

简单上传

以下代码用于简单上传时禁止覆盖同名文件:

package main

import (
    "context"
    "fmt"
    "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
    "os"
    "strings"
)

func checkErr(err error) {
    if err != nil {
       if serverErr, ok := err.(*tos.TosServerError); ok {
          fmt.Println("Error:", serverErr.Error())
          fmt.Println("Request ID:", serverErr.RequestID)
          fmt.Println("Response Status Code:", serverErr.StatusCode)
          fmt.Println("Response Header:", serverErr.Header)
          fmt.Println("Response Err Code:", serverErr.Code)
          fmt.Println("Response Err Msg:", serverErr.Message)
       } else if clientErr, ok := err.(*tos.TosClientError); ok {
          fmt.Println("Error:", clientErr.Error())
          fmt.Println("Client Cause Err:", clientErr.Cause.Error())
       } else {
          fmt.Println("Error:", err)
       }
       panic(err)
    }
}

func main() {
    var (
       accessKey = os.Getenv("TOS_ACCESS_KEY")
       secretKey = os.Getenv("TOS_SECRET_KEY")
       // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
       endpoint = "https://tos-cn-beijing.volces.com"
       region   = "cn-beijing"
       // 填写 BucketName
       bucketName = "*** Provide your bucket name ***"

       objectKey = "*** Provide your object key ***"
       ctx       = context.Background()
    )
    // 初始化客户端
    client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
    checkErr(err)
    
    // ForbidOverwrite 为 true 时表示禁止覆盖同名对象
    // 当同名对象已存在,则会返回 err。
    body := strings.NewReader("Hello TOS")
    output, err := client.PutObjectV2(ctx, &tos.PutObjectV2Input{
       PutObjectBasicInput: tos.PutObjectBasicInput{
          Bucket:          bucketName,
          Key:             objectKey,
          ForbidOverwrite: true,
       },
       Content: body,
    })
    checkErr(err)
    fmt.Println("PutObjectV2 Request ID:", output.RequestID)
}

拷贝文件

以下代码用于拷贝文件时禁止覆盖同名文件:

package main

import (
    "context"
    "fmt"
    "os"

    "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
)

func checkErr(err error) {
    if err != nil {
       if serverErr, ok := err.(*tos.TosServerError); ok {
          fmt.Println("Error:", serverErr.Error())
          fmt.Println("Request ID:", serverErr.RequestID)
          fmt.Println("Response Status Code:", serverErr.StatusCode)
          fmt.Println("Response Header:", serverErr.Header)
          fmt.Println("Response Err Code:", serverErr.Code)
          fmt.Println("Response Err Msg:", serverErr.Message)
       } else if clientErr, ok := err.(*tos.TosClientError); ok {
          fmt.Println("Error:", clientErr.Error())
          fmt.Println("Client Cause Err:", clientErr.Cause.Error())
       } else {
          fmt.Println("Error:", err)
       }
       panic(err)
    }
}

func main() {
    var (
       accessKey = os.Getenv("TOS_ACCESS_KEY")
       secretKey = os.Getenv("TOS_SECRET_KEY")
       // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
       endpoint = "https://tos-cn-beijing.volces.com"
       region   = "cn-beijing"
       // 填写 BucketName
       bucketName = "*** Provide your bucket name ***"
       // 复制源对象 key
       srcObjectKey = "srcObjectKey"
       dstObjectKey = "objectKey"
       ctx          = context.Background()
    )
    // 初始化客户端
    client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
    checkErr(err)
    // ForbidOverwrite 为 true 时表示禁止覆盖同名对象
    // 当同名对象已存在,则会返回 err。
    output, err := client.CopyObject(ctx, &tos.CopyObjectInput{
       Bucket:          bucketName,
       Key:             dstObjectKey,
       SrcBucket:       bucketName,
       SrcKey:          srcObjectKey,
       ForbidOverwrite: true,
    })
    checkErr(err)
    fmt.Println("CopyObject Request ID:", output.RequestID)
}

分片上传

以下代码用于分片上传时禁止覆盖同名文件:

package main

import (
    "context"
    "fmt"
    "io"
    "os"

    "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
)

func checkErr(err error) {
    if err != nil {
       if serverErr, ok := err.(*tos.TosServerError); ok {
          fmt.Println("Error:", serverErr.Error())
          fmt.Println("Request ID:", serverErr.RequestID)
          fmt.Println("Response Status Code:", serverErr.StatusCode)
          fmt.Println("Response Header:", serverErr.Header)
          fmt.Println("Response Err Code:", serverErr.Code)
          fmt.Println("Response Err Msg:", serverErr.Message)
       } else if clientErr, ok := err.(*tos.TosClientError); ok {
          fmt.Println("Error:", clientErr.Error())
          fmt.Println("Client Cause Err:", clientErr.Cause.Error())
       } else {
          fmt.Println("Error:", err)
       }
       panic(err)
    }
}

func main() {
    var (
       accessKey = os.Getenv("TOS_ACCESS_KEY")
       secretKey = os.Getenv("TOS_SECRET_KEY")
       // Bucket 对应的 Endpoint,以华北2(北京)为例:https://tos-cn-beijing.volces.com
       endpoint = "https://tos-cn-beijing.volces.com"
       region   = "cn-beijing"
       // 填写 BucketName
       bucketName = "*** Provide your bucket name ***"

       // 指定的 ObjectKey
       objectKey = "*** Provide your object name ***"
       ctx       = context.Background()
    )

    // 需要上传的文件路径
    localFile := "/root/example.txt"
    fd, err := os.Open(localFile)
    checkErr(err)
    defer fd.Close()
    stat, err := os.Stat(localFile)
    checkErr(err)
    fileSize := stat.Size()
    // partNumber 编号从 1 开始
    partNumber := 1
    // part size 大小设置为 20M
    partSize := int64(20 * 1024 * 1024)
    offset := int64(0)

    // 初始化客户端
    client, err := tos.NewClientV2(endpoint, tos.WithRegion(region), tos.WithCredentials(tos.NewStaticCredentials(accessKey, secretKey)))
    checkErr(err)

    // 步骤1 初始化分片
    // ForbidOverwrite 为 true 时表示禁止覆盖同名对象
    // 当同名对象已存在,则会返回 err。
    createMultipartOutput, err := client.CreateMultipartUploadV2(ctx, &tos.CreateMultipartUploadV2Input{
       Bucket:          bucketName,
       Key:             objectKey,
       ForbidOverwrite: true,
    })
    checkErr(err)
    fmt.Println("CreateMultipartUploadV2 Request ID:", createMultipartOutput.RequestID)
    // 获取到上传的 UploadID
    fmt.Println("CreateMultipartUploadV2 Upload ID:", createMultipartOutput.UploadID)

    // 步骤2 上传分片
    var parts []tos.UploadedPartV2
    for offset < fileSize {
       uploadSize := partSize
       // 最后一个分片
       if fileSize-offset < partSize {
          uploadSize = fileSize - offset
       }
       fd.Seek(offset, io.SeekStart)
       partOutput, err := client.UploadPartV2(ctx, &tos.UploadPartV2Input{
          UploadPartBasicInput: tos.UploadPartBasicInput{
             Bucket:     bucketName,
             Key:        objectKey,
             UploadID:   createMultipartOutput.UploadID,
             PartNumber: partNumber,
          },
          Content:       io.LimitReader(fd, uploadSize),
          ContentLength: uploadSize,
       })
       checkErr(err)
       fmt.Println("upload Request ID:", partOutput.RequestID)
       parts = append(parts, tos.UploadedPartV2{PartNumber: partNumber, ETag: partOutput.ETag})
       offset += uploadSize
       partNumber++
    }

    // 步骤3 合并分片
    // ForbidOverwrite 为 true 时表示禁止覆盖同名对象
    // 当同名对象已存在,则会返回 err。
    completeOutput, err := client.CompleteMultipartUploadV2(ctx, &tos.CompleteMultipartUploadV2Input{
       Bucket:          bucketName,
       Key:             objectKey,
       UploadID:        createMultipartOutput.UploadID,
       Parts:           parts,
       ForbidOverwrite: true,
    })
    checkErr(err)
    fmt.Println("CompleteMultipartUploadV2 Request ID:", completeOutput.RequestID)

}