全部产品
Search
文档中心

对象存储 OSS:Python数据校验

更新时间:Dec 20, 2023

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

注意事项

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

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

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

MD5校验

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

上传文件时进行MD5校验:

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
# 填写Bucket名称,例如examplebucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# 填写Object的完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
object_name = 'exampledir/exampleobject.txt'
# 填写要上传文件的本地路径。在上传时,该变量的值将作为上传的内容传输到OSS。该文件没有格式限制,可以是任何类型的文件内容,例如文本、图片、视频、音频等。
with open('/Users/test/Desktop/demo.txt', 'rb') as file:
    content = file.read()

# 根据实际内容计算上传内容对应的MD5。
content_md5 = oss2.utils.content_md5(content);
print('content_md5', content_md5)

# 上传请求中携带'Content-MD5'的header,服务器会校验上传内容的MD5,用于保证上传内容的完整性和正确性。
headers = dict()
headers['Content-MD5'] = content_md5
bucket.put_object(object_name, content, headers=headers)
说明

put_object、append_Object、post_Object、upload_part均支持MD5校验。

CRC64校验

使用CRC校验数据时,有如下注意事项:

说明
  • put_object、get_object、append_object、upload_part支持CRC64校验。上传文件时默认开启CRC校验,如果客户端计算的CRC值与服务端返回的CRC值不一致, 则会抛出InconsistentError异常。

  • 范围下载不支持CRC64校验。

  • CRC64校验会占用一定的CPU,对上传、下载速度均会有影响。

  • 下载文件时CRC64校验

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

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    # yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    # 填写Bucket名称,例如examplebucket。
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
    # 填写Object的完整路径。Object完整路径中不能包含Bucket名称。
    object_name = 'yourObjectName'
    
    # 查看是否已默认开启crc校验。
    print('bucket.enable-crc:',  bucket.enable_crc)
    
    # bucket.get_object的返回值是一个类文件对象(File-Like Object),同时也是一个可迭代对象(Iterable)。
    object_stream = bucket.get_object(object_name)
    print(object_stream.read())
    
    # 由于get_object接口返回的是一个stream流,需要执行read()后才能计算出返回Object数据的CRC checksum,因此需要在调用该接口后做CRC校验。
    if object_stream.client_crc != object_stream.server_crc:
      print("The CRC checksum between client and server is inconsistent!")
  • 追加上传时CRC64校验

    追加上传时,如果指定了init_crc参数,则默认开启CRC64校验。

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    # yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    # 填写Bucket名称,例如examplebucket。
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
    
    object_name = "yourAppendObjectName"
    first_content = "yourFirstContent"
    second_content = "yourSecondContent"
    
    # 第一次追加上传。
    # 在指定了init_crc的情况下,SDK默认会对返回结果进行crc校验。
    result = bucket.append_object(object_name, 0, first_content, init_crc=0)
    
    # 第二次追加上传。
    # 指定init_crc为已上传数据的crc。
    result = bucket.append_object(object_name, result.next_position, second_content, init_crc=result.crc)

相关文档

关于数据校验的完整示例代码,请参见GitHub示例