全部产品
Search
文档中心

对象存储 OSS:Go禁止覆盖同名文件

更新时间:Dec 20, 2023

默认情况下,如果新添加文件与现有文件(Object)同名且对该文件有访问权限,则新添加的文件将覆盖原有的文件。本文介绍如何通过设置请求头x-oss-forbid-overwrite在简单上传、拷贝文件及分片上传等场景中禁止覆盖同名文件。

注意事项

  • 本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见访问域名和数据中心

  • 本文以从环境变量读取访问凭证为例。如何配置访问凭证,请参见配置访问凭证

  • 本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见初始化

简单上传

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

package main

import (
    "fmt"
    "os"
    "strings"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    /// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 创建OSSClient实例。
    // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // yourBucketName填写存储空间名称。
    bucket, err := client.Bucket("yourBucketName")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 指定是否覆盖同名文件。
    // 不指定oss.ForbidOverWrite时,默认覆盖同名Object。
    // 指定oss.ForbidOverWrite为false时,表示允许覆盖同名Object。
    // 指定oss.ForbidOverWrite为true时,表示禁止覆盖同名Object,如果同名Object已存在,程序将报错。
    forbidWrite := oss.ForbidOverWrite(true)

    // 上传字符串。
    // yourObjectName填写不包含Bucket名称在内的Object的完整路径。
    err = bucket.PutObject("yourObjectName", strings.NewReader("yourObjectValue"), forbidWrite)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

拷贝文件

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

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    /// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 创建OSSClient实例。
    // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // yourBucketName填写存储空间名称。
    bucketName := "yourBucketName"
    // yourObjectName填写不包含Bucket名称在内的源Object的完整路径。
    objectName := "yourObjectName"
    // yourDestObjectName填写不包含Bucket名称在内的目标Object的完整路径。
    destObjectName := "yourDestObjectName"

    bucket, err := client.Bucket(bucketName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 指定是否覆盖同名目标文件。
    // 不指定oss.ForbidOverWrite时,默认覆盖同名目标Object。
    // 指定oss.ForbidOverWrite为false时,表示允许覆盖同名目标Object。
    // 指定oss.ForbidOverWrite为true时,表示禁止覆盖同名目标Object,如果同名目标Object已存在,程序将报错。
    forbidWrite := oss.ForbidOverWrite(true)

    // 拷贝文件到同一个存储空间的另一个文件。
    _, err = bucket.CopyObject(objectName, destObjectName, forbidWrite)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}

分片上传

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

package main

import (
    "fmt"
    "os"

    "github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
    /// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 创建OSSClient实例。
    // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // yourBucketName填写存储空间名称。
    bucketName := "yourBucketName"
    // yourObjectName填写不包含Bucket名称在内的Object的完整路径。
    objectName := "yourObjectName"
   // yourLocalFilename填写本地文件的完整路径。
    locaFilename := "yourLocalFilename"

    bucket, err := client.Bucket(bucketName)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    chunks, err := oss.SplitFileByPartNum(locaFilename, 3)
    fd, err := os.Open(locaFilename)
    defer fd.Close()

    // 指定是否覆盖同名文件。
    // 不指定oss.ForbidOverWrite时,默认覆盖同名Object。
    // 指定oss.ForbidOverWrite为false时,表示允许覆盖同名Object。
    // 指定oss.ForbidOverWrite为true时,表示禁止覆盖同名Object,如果同名Object已存在,程序将报错。
    forbidWrite := oss.ForbidOverWrite(true)

    // 步骤1:初始化一个分片上传事件。
    imur, err := bucket.InitiateMultipartUpload(objectName, forbidWrite)
    // 步骤2:上传分片。
    var parts []oss.UploadPart
    for _, chunk := range chunks {
        fd.Seek(chunk.Offset, os.SEEK_SET)
        // 对每个分片调用UploadPart方法上传。
        part, err := bucket.UploadPart(imur, fd, chunk.Size, chunk.Number)
        if err != nil {
            fmt.Println("Error:", err)
            os.Exit(-1)
        }
        parts = append(parts, part)
    }

    // 步骤3:完成分片上传,禁止覆盖同名文件。
    cmur, err := bucket.CompleteMultipartUpload(imur, parts, forbidWrite)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    fmt.Println("cmur:", cmur)
}

相关文档