Python SDK提供了两个基本的下载接口:
- Bucket.get_object :它的返回值是一个类文件对象(file-like object),同时也是一个可迭代对象(iterable)
- Bucket.get_object_to_file :直接下载到本地文件
此外,还提供了一个易用性接口:
- oss2.resumable_download 以帮助用户进行断点续传、并行下载。
流式下载
下面的例子一次性读取OSS文件,并打印出来:
- # -*- coding: utf-8 -*-
- import oss2
- auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
- bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
- remote_stream = bucket.get_object('remote.txt')
- print(remote_stream.read())
既然是类文件对象,我们就可以方便的使用一些库函数,如下载到本地文件:
- import shutil
- remote_stream = bucket.get_object('remote.txt')
- with open('local-backup.txt', 'wb') as local_fileobj:
- shutil.copyfileobj(remote_stream, local_fileobj)
由于返回值又是一个可迭代对象,所以可以把它流式的拷贝到另一个Object:
- remote_stream = bucket.get_object('remote.txt')
- bucket.put_object('remote-backup.txt', remote_stream)
下载到本地文件
下面的代码把OSS上的remote.txt文件,下载到当前目录下的local-backup.txt。
- bucket.get_object_to_file('remote.txt', 'local-backup.txt')
指定下载范围
通过可选参数 byte_range ,可以指定下载的范围。byte_range是一个tuple,表示范围的起止字节。下面的代码会下载前100个字节的数据:
- remote_stream = bucket.get_object('remote.txt', byte_range=(0, 99))
注意
- byte_range表示的是字节偏移量的闭区间,字节偏移从0开始计。如(0, 99)表示从第0个字节到第99个字节(包含在内),共计100个字节的数据。
进度条
下载接口提供了可选参数 progress_callback ,用来帮助实现进度条功能。下面的代码实现了一个简单的命令行下的进度显示功能(新建一个Python源文件):
- # -*- coding: utf-8 -*-
- from __future__ import print_function
- import os, sys
- import oss2
- auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
- bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
- def percentage(consumed_bytes, total_bytes):
- if total_bytes:
- rate = int(100 * (float(consumed_bytes) / float(total_bytes)))
- print('\r{0}% '.format(rate), end='')
- sys.stdout.flush()
- bucket.get_object_to_file('remote.txt', 'local-backup.txt', progress_callback=percentage)
注意
- 当待HTTP响应头部没有Content-Length头时,progress_callback的第二个参数(total_bytes)为None。
- 进度条的完整示例代码请参看 GitHub 。
断点续传
当需要下载的文件很大,或网络状况不够理想,往往下载到中途就失败了。如果下次重试,还需要重新下载,就会浪费时间和带宽。为此,Python SDK 提供了一个易用性接口 oss2.resumable_download 用于断点续传。
下面的代码把OSS文件remote.txt下载到本地当前目录,并重命名为local.txt。
- oss2.resumable_download(bucket, 'remote.txt', 'local.txt')
断点续传的过程大致如下:
- 在本地创建一个临时文件,文件名由原始文件名加上一个随机的后缀组成;
- 通过指定HTTP请求的 Range 头,按照范围读取OSS文件,并写入到临时文件里相应的位置;
- 下载完成之后,把临时文件重名为目标文件。
在上述过程中,断点信息,即已经下载的范围等信息,会保存在本地磁盘上。如果因为某种原因下载中断了,后续重试本次下载,就会读取断点信息,然后只下载缺失的部分。
下面是一个完全定制化的例子:
- oss2.resumable_download(bucket, 'remote.txt', 'local.txt',
- store=oss2.ResumableDownloadStore(root='/tmp'),
- multiget_threshold=20*1024*1024,
- part_size=10*1024*1024,
- num_threads=3)
含义是
- ResumableDownloadStore 指定把断点信息保存到 /tmp/.py-oss-download 目录下
- multiget_threshold 指明当文件长度不小于20MB时,就采用分范围下载
- part_size 建议每次下载10MB。如果文件太大,那么实际的值会大于指定值
- num_threads 指定并发下载线程数为3
使用该函数应注意如下细节:
- 对同样的源文件、目标文件,避免多个程序(线程)同时调用该函数。因为断点信息会在磁盘上互相覆盖,或临时文件名会冲突。
- 避免使用太小的范围(分片),即 part_size 参数不宜过小,建议大于或等于 oss2.defaults.multiget_part_size 。
- 如果目标文件已经存在,那么该函数会覆盖此文件。
注意
- 请把 oss2.defaults.connection_pool_size 设成大于或等于线程数。
- 要求 2.1.0 及以后版本