Python范围下载

如果仅需要文件中的部分数据,您可以使用范围下载,下载指定范围内的数据。

注意事项

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

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

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

  • 要范围下载,您必须有oss:GetObject权限。具体操作,请参见RAM用户授权自定义的权限策略

指定正常的下载范围

以下代码用于指定正常的下载范围来下载文件。

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"

# 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数
region = "cn-hangzhou"

# yourBucketName填写存储空间名称。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)

# 对于1000字节大小的文件,正常的下载范围取值为0~999。
# 获取0~999字节范围内的数据,包括0和999,共1000个字节的数据。如果指定的范围无效(比如开始或结束位置的指定值为负数,或指定值大于文件大小),则下载整个文件。
object_stream = bucket.get_object('<yourObjectName>', byte_range=(0, 999))

指定异常的下载范围

假设现有大小为1000 BytesObject,则指定的正常下载范围应为0~999。如果指定范围不在有效区间,会导致Range不生效,响应返回值为200,并传送整个Object的内容。请求不合法的示例及返回说明如下:

  • 若指定了Range: bytes=500~2000,此时范围末端取值不在有效区间,返回整个文件的内容,且HTTP Code200。

  • 若指定了Range: bytes=1000~2000,此时范围首端取值不在有效区间,返回整个文件的内容,且HTTP Code200。

标准行为范围下载

在请求中增加请求头x-oss-range-behavior:standard,则改变指定范围不在有效区间时OSS的下载行为。假设现有大小为1000 BytesObject:

  • 若指定了Range: bytes=500~2000,此时范围末端取值不在有效区间,返回500~999字节范围内容,且HTTP Code206。

  • 若指定了Range: bytes=1000~2000,此时范围首端取值不在有效区间,返回HTTP Code416,错误码为InvalidRange。

以下代码用于标准行为范围下载。

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"

# 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数
region = "cn-hangzhou"

# yourBucketName填写存储空间名称。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)


# 创建大小为1000 Bytes的object。
object_name = 'rangeTest.txt'
content = 'a' * 1000
bucket.put_object(object_name, content)

headers = {'x-oss-range-behavior': 'standard'}

# 如果范围末端取值不在有效区间,则返回500~999字节范围内容,且HTTP Code为206。
object_stream = bucket.get_object(object_name, byte_range=(500, 2000), headers=headers)
print('standard get 500~2000 http status code:', object_stream.status)
print('standard get 500~2000 contnet_length:', object_stream.content_length)

try:
    # 如果范围首端取值不在有效区间,则抛出异常,返回HTTP Code为416,错误码为InvalidRange。
    object_stream = bucket.get_object(object_name, byte_range=(1000, 2000), headers=headers)
except oss2.exceptions.ServerError as e:
    print('standard get 1000~2000 http status code:', e.status)
    print('standard get 1000~2000 error code:', e.code)  

相关文档

  • 关于范围下载的完整示例代码,请参见GitHub示例

  • 关于范围下载的API接口说明,请参见GetObject