全部产品
对象存储 OSS

下载文件

更新时间:2017-06-07 13:26:11   分享:   

Python SDK提供了两个基本的下载接口:

  • Bucket.get_object :它的返回值是一个类文件对象(file-like object),同时也是一个可迭代对象(iterable)
  • Bucket.get_object_to_file :直接下载到本地文件

此外,还提供了一个易用性接口:

  • oss2.resumable_download 以帮助用户进行断点续传、并行下载。

流式下载

下面的例子一次性读取OSS文件,并打印出来:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
  4. bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
  5. remote_stream = bucket.get_object('remote.txt')
  6. print(remote_stream.read())

既然是类文件对象,我们就可以方便的使用一些库函数,如下载到本地文件:

  1. import shutil
  2. remote_stream = bucket.get_object('remote.txt')
  3. with open('local-backup.txt', 'wb') as local_fileobj:
  4. shutil.copyfileobj(remote_stream, local_fileobj)

由于返回值又是一个可迭代对象,所以可以把它流式的拷贝到另一个Object:

  1. remote_stream = bucket.get_object('remote.txt')
  2. bucket.put_object('remote-backup.txt', remote_stream)

下载到本地文件

下面的代码把OSS上的remote.txt文件,下载到当前目录下的local-backup.txt。

  1. bucket.get_object_to_file('remote.txt', 'local-backup.txt')

指定下载范围

通过可选参数 byte_range ,可以指定下载的范围。byte_range是一个tuple,表示范围的起止字节。下面的代码会下载前100个字节的数据:

  1. remote_stream = bucket.get_object('remote.txt', byte_range=(0, 99))

注意

  • byte_range表示的是字节偏移量的闭区间,字节偏移从0开始计。如(0, 99)表示从第0个字节到第99个字节(包含在内),共计100个字节的数据。

进度条

下载接口提供了可选参数 progress_callback ,用来帮助实现进度条功能。下面的代码实现了一个简单的命令行下的进度显示功能(新建一个Python源文件):

  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function
  3. import os, sys
  4. import oss2
  5. auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
  6. bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
  7. def percentage(consumed_bytes, total_bytes):
  8. if total_bytes:
  9. rate = int(100 * (float(consumed_bytes) / float(total_bytes)))
  10. print('\r{0}% '.format(rate), end='')
  11. sys.stdout.flush()
  12. 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。

  1. oss2.resumable_download(bucket, 'remote.txt', 'local.txt')

断点续传的过程大致如下:

  1. 在本地创建一个临时文件,文件名由原始文件名加上一个随机的后缀组成;
  2. 通过指定HTTP请求的 Range 头,按照范围读取OSS文件,并写入到临时文件里相应的位置;
  3. 下载完成之后,把临时文件重名为目标文件。

在上述过程中,断点信息,即已经下载的范围等信息,会保存在本地磁盘上。如果因为某种原因下载中断了,后续重试本次下载,就会读取断点信息,然后只下载缺失的部分。

下面是一个完全定制化的例子:

  1. oss2.resumable_download(bucket, 'remote.txt', 'local.txt',
  2. store=oss2.ResumableDownloadStore(root='/tmp'),
  3. multiget_threshold=20*1024*1024,
  4. part_size=10*1024*1024,
  5. 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 及以后版本
本文导读目录
本文导读目录
以上内容是否对您有帮助?