Go數(shù)據(jù)校驗
OSS提供基于MD5和CRC64的數(shù)據(jù)校驗,確保上傳、下載和拷貝文件(Object)過程中的數(shù)據(jù)完整性。
注意事項
本文以華東1(杭州)外網(wǎng)Endpoint為例。如果您希望通過與OSS同地域的其他阿里云產(chǎn)品訪問OSS,請使用內(nèi)網(wǎng)Endpoint。關(guān)于OSS支持的Region與Endpoint的對應關(guān)系,請參見OSS訪問域名、數(shù)據(jù)中心、開放端口。
本文以從環(huán)境變量讀取訪問憑證為例。如何配置訪問憑證,請參見配置訪問憑證。
本文以OSS域名新建OSSClient為例。如果您希望通過自定義域名、STS等方式新建OSSClient,請參見初始化。
MD5校驗
當上傳文件時,如果指定了Content-MD5
,OSS將根據(jù)接收到的數(shù)據(jù)重新計算MD5值。若OSS計算出的MD5值與上傳時提供的值不符,將返回 InvalidDigest
異常,以此確保數(shù)據(jù)的完整性和準確性。遇到InvalidDigest
異常時,建議檢查文件是否在傳輸過程中發(fā)生改變或損壞,并重新上傳文件。
putObject、getObject、appendObject、postObject、uploadPart支持MD5校驗。
以下代碼用于上傳文件時進行MD5校驗:
package main
import (
"crypto/md5"
"encoding/base64"
"log"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
// 計算給定內(nèi)容的MD5校驗碼
func calculateMD5(content string) string {
h := md5.New()
h.Write([]byte(content))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
func main() {
// 從環(huán)境變量中加載OSS訪問憑證
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// 替換為實際的Bucket名稱
bucketName := "yourBucketName"
// 創(chuàng)建OSS客戶端
// yourEndpoint填寫B(tài)ucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
// yourRegion填寫B(tài)ucket所在地域,以華東1(杭州)為例,填寫為cn-hangzhou。其它Region請按實際情況填寫。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 設(shè)置簽名版本
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// 獲取指定的Bucket
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket %s: %v", bucketName, err)
}
// 要上傳的內(nèi)容
content := "yourObjectValue" // 替換為實際要上傳的內(nèi)容
objectName := "yourObjectName" // 替換為實際的對象名稱
// 計算內(nèi)容的MD5校驗碼
contentMD5 := calculateMD5(content)
// 上傳文件到OSS
err = bucket.PutObject(objectName, strings.NewReader(content), oss.ContentMD5(contentMD5))
if err != nil {
log.Fatalf("Failed to upload object %s: %v", objectName, err)
}
log.Printf("Object '%s' uploaded successfully.", objectName)
}
CRC64校驗
CRC64 校驗注意事項:
putObject、getObject、appendObject、uploadPart支持CRC64校驗。
上傳、下載和拷貝文件時,默認啟用 CRC 數(shù)據(jù)校驗。如果客戶端計算的 CRC 值與服務(wù)端返回的 CRC 值不一致,將返回錯誤。
范圍下載不支持 CRC64 校驗。
啟用 CRC64 校驗會占用一定的 CPU 資源,對上傳、下載速度均會有影響。
以下代碼用于追加上傳文件時進行CRC64數(shù)據(jù)完整性校驗:
package main
import (
"log"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 從環(huán)境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Failed to create credentials provider: %v", err)
}
// 創(chuàng)建OSSClient實例。
// yourEndpoint填寫B(tài)ucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
// yourRegion填寫B(tài)ucket所在地域,以華東1(杭州)為例,填寫為cn-hangzhou。其它Region請按實際情況填寫。
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
// 設(shè)置簽名版本
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Failed to create OSS client: %v", err)
}
// yourBucketName填寫存儲空間名稱。
bucketName := "yourBucketName" // 替換為實際的Bucket名稱
bucket, err := client.Bucket(bucketName)
if err != nil {
log.Fatalf("Failed to get bucket %s: %v", bucketName, err)
}
// 定義要追加的Object名稱
objectName := "yourObjectName" // 替換為實際的Object名稱
// 第一次追加的位置是0,返回值為下一次追加的位置。后續(xù)追加的位置是追加前文件的長度。
request := &oss.AppendObjectRequest{
ObjectKey: objectName,
Reader: strings.NewReader("YourObjectAppendValue1"),
Position: 0,
}
// 第一次追加時,初始化crc的值為0。
options := []oss.Option{oss.InitCRC(0)}
result, err := bucket.DoAppendObject(request, options)
if err != nil {
log.Fatalf("Failed to append object %s for the first time: %v", objectName, err)
}
log.Printf("First append successful. Next position: %d", result.NextPosition)
// 第二次追加的位置從第一次的返回長度開始。
request = &oss.AppendObjectRequest{
ObjectKey: objectName,
Reader: strings.NewReader("YourObjectAppendValue2"),
Position: result.NextPosition,
}
// 第二次追加的初始化crc值為第一次返回值。
options = []oss.Option{oss.InitCRC(result.CRC)}
result, err = bucket.DoAppendObject(request, options)
if err != nil {
log.Fatalf("Failed to append object %s for the second time: %v", objectName, err)
}
log.Printf("Second append successful. Next position: %d", result.NextPosition)
// 您可以進行多次AppendObject操作。
log.Printf("All appends completed successfully.")
}