OSS提供基于MD5和CRC64的数据校验,确保上传、下载和拷贝文件(Object)过程中的数据完整性。

MD5校验

如果上传文件时设置了Content-MD5,OSS会根据接收的内容计算MD5。OSS计算的MD5值和上传提供的MD5值不一致时,则返回InvalidDigest异常,从而保证数据的完整性。返回InvalidDigest异常后,您需要重新上传文件。

以下代码用于上传文件时进行MD5校验:

package main

import (
    "crypto/md5"
    "encoding/base64"
    "fmt"
    "os"
    "strings"

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

func main() {
    // 创建OSSClient实例。
    client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 获取存储空间。
    bucket, err := client.Bucket("<yourBucketName>")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 获取文件内容。
    content := "<yourObjectValue>"

    // 计算md5值。
    h := md5.New()
    h.Write([]byte(content))
    strMd5 := base64.StdEncoding.EncodeToString(h.Sum(nil))

    // 简单上传。
    err = bucket.PutObject("<yourObjectName>", strings.NewReader(content), oss.ContentMD5(strMd5))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
}
说明 putObject、getObject、appendObject、postObject、uploadPart支持MD5校验。

CRC64校验

上传、下载和拷贝文件时默认开启CRC数据校验,确保数据的完整性。

使用CRC64校验,有如下注意事项:

  • putObject、getObject、appendObject、uploadPart支持CRC64校验。上传时默认开启CRC校验,如果客户端计算的CRC值与服务端返回的CRC值不一致, 则会返回错误。
  • 范围下载不支持CRC64校验。
  • CRC64校验会占用一定的CPU,对上传、下载速度均会有影响。

以下代码用于追加上传文件时进行CRC64数据完整性校验:

package main

import (
    "fmt"
    "os"
    "strings"

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

func main() {
    // 创建OSSClient实例。
    client, err := oss.New("<yourEndpoint>", "<yourAccessKeyId>", "<yourAccessKeySecret>")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 获取存储空间。
    bucket, err := client.Bucket("<yourBucketName>")
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 第一次追加的位置是0,返回值为下一次追加的位置。后续追加的位置是追加前文件的长度。
    request := &oss.AppendObjectRequest{
        ObjectKey: "<yourObjectName>",
        Reader:    strings.NewReader("<YourObjectAppendValue1>"),
        Position:  0,
    }

    // 第一次追加时,初始化crc的值为0。
    options := []oss.Option{oss.InitCRC(0)}
    result, err := bucket.DoAppendObject(request, options)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }

    // 第二次追加的位置从第一次的返回长度开始。
    request = &oss.AppendObjectRequest{
        ObjectKey: "<yourObjectName>",
        Reader:    strings.NewReader("<YourObjectAppendValue2>"),
        Position:  result.NextPosition,
    }

    // 第二次追加的初始化crc值为第一次返回值。
    options = []oss.Option{oss.InitCRC(result.CRC)}
    result, err = bucket.DoAppendObject(request, options)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    // 您可以进行多次AppendObject操作。
}