下载对象

MSS Python SDK 提供了三个基本的下载对象接口:

  1. mssapi.s3.key.Key.get_contents_to_filename
  2. mssapi.s3.key.Key.get_contents_to_file
  3. mssapi.s3.key.Key.get_contents_as_string

注意:如果对象下载过程中,出现异常,需要调用 mssapi.s3.key.Key.close 接口清除当前连接中的脏数据。

下载到新文件

# b0是下载对象所在的bucket,类型为:mssapi.s3.bucket.Bucket
k0 = b0.get_key('您想要下载的对象名字')
local_filename = '您想要保存在本地的文件名'
try:
    k0.get_contents_to_filename(local_filename)
finally:
    # 清除当前连接中未读取的数据
    k0.close()

mssapi.s3.key.Key.get_contents_to_filename 接口参数:

参数 类型 默认值 必选 注释
filename string - 对象保存到本地的文件名,注意:与 filename 重名的文件会被完全覆盖
headers dict None 下载对象请求中可以额外指定的 HTTP 头部字段

下载到已有文件

# b0是下载对象所在的bucket,类型为:mssapi.s3.bucket.Bucket
k0 = b0.get_key('您想要下载的对象名字')

current_filename = '您需要保存的文件名字'
with open(current_filename, 'r+b') as fp:
    try:
        k0.get_contents_to_file(fp)
    finally:
        k0.close()

mssapi.s3.key.Key.get_contents_to_file 接口参数:

参数 类型 默认值 必选 注释
fp file - 当前已打开文件句柄,注意:此接口会从 fp.tell() 位置开始写下载的对象数据
headers dict None 下载对象请求中可以额外指定的 HTTP 头部字段

下载到内存缓冲区

# b0是下载对象所在的bucket,类型为:mssapi.s3.bucket.Bucket
k0 = b0.get_key('您想要下载的对象名字')

try: 
    result = k0.get_contents_as_string(encoding='utf-8')
finally:
    k0.close()
print result
assert isinstance(result, unicode)

mssapi.s3.key.Key.get_contents_as_string 接口参数:

参数 类型 默认值 必选 注释
encoding string None 文本编码方式,比如 utf-8, iso-8859-1 等等;如果设定此选项,则返回 unicode 对象,否则返回 bytes 对象
headers dict None 下载对象请求中可以额外指定的 HTTP 头部字段

范围下载

MSS 是支持 HTTP Range 请求的,通过在 HTTP 头部指定 Range 字段可以下载对象的指定范围内容(有关 HTTP Range 请求的内容请参考RFC2733)。调用 get_contents_as_string 时,通过设定 HTTP Rage Header 来实现范围下载的例子:

import hashlib
# b0是下载对象所在的bucket,类型为:mssapi.s3.bucket.Bucket
k0 = b0.get_key('您想要下载的对象名字')

# 通过Range下载整个文件
offset = 0
hash_md5 = hashlib.md5()
with open('本地的文件名', 'wb') as fp:
    while offset < k0.size:
        range_size = min(1024*1024, k0.size - offset)
        try:
            bytes = k0.get_contents_as_string(headers={'Range': bytes=%d-%d' % (offset, offset + range_size - 1)})
        finally:
            k0.close()
        fp.write(bytes)
        offset += range_size
        hash_md5.update(bytes)

assert k0.etag.strip('"') == hash_md5.hexdigest()

流式下载

mssapi.s3.key.Key 实现了迭代器和 read 接口,通过这两种方式都可以实现流式下载:

import hashlib

k0 = b0.get_key('流式下载的对象名字')

# 通过read接口流式读取MSS对象中的数据计算md5
offset = 0
hash_md5 = hashlib.md5()
try:
    while offset < k0.size:
        part_size = min(1000, k0.size - offset)
        bytes = k1.read(part_size)
        offset += part_size
        hash_md5.update(bytes)
finally:
    k0.close()

# 比较流式读取的结果与MSS存储的数据是否一致
assert k0.etag.strip('"') == hash_md5.hexdigest()

# 迭代遍历Key对象实现流式读取
k0 = b0.get_key('流式下载的对象名字')

offset = 0
hash_md5 = hashlib.md5()
try:
    for bytes in k0:
        hash_md5.update(bytes)
finally:
    k0.close()

assert k0.etag.strip('"') == hash_md5.hexdigest()

注意:

  1. 当使用 MSS 对象作为流式上传的源时,必须要保证源和目标对应不同的 MSS 集群。
  2. 当对 mssapi.s3.key.Key 对象进行流式读取时,最后必须调用 Key.close 接口。