开发者社区> 问答> 正文

Python-SDK之如何实现上传文件(一)?

OSS有多种上传方式,不同的上传方式能够上传的数据大小也不一样。普通上传(PutObject)、追加上传(AppendObject)最多只能上传小于或等于5GB的文件;而分片上传每个分片可以达到5GB,合并后的文件能够达到48.8TB。
首先介绍普通上传,我们会详细展示提供数据的各种方式,即方法中的 data 参数。其他上传接口有类似的data参数,不再赘述。

普通上传


通过 Bucket.put_object 方法,可以上传一个普通文件。

上传字符串


上传内存中的字符串:

  1. # -*- coding: utf-8 -*-
  2. import oss2
  3. auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
  4. bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
  5. bucket.put_object('remote.txt', 'content of object')

也可以指定上传的是bytes:
  1. bucket.put_object('remote.txt', b'content of object')

或是指定为unicode:
  1. bucket.put_object('remote.txt', u'content of object')

事实上,oss2.Bucket.put_object的第二个参数(参数名为data)可以接受两种类型的字符串:
  • bytes:直接上传
  • unicode:会自动转换为UTF-8编码的bytes进行上传


上传本地文件

  1. with open('local.txt', 'rb') as fileobj:
  2.     bucket.put_object('remote.txt', fileobj)

对比上传字符串的代码,注意到数据参数既可以是字符串,也可以是这里的文件对象(file object)。

注意:
  • 必须以二进制的方式打开文件,因为内部实现需要知道文件包含的字节数。

Python SDK还提供了一个便捷的方法完成上面的工作:
  1. bucket.put_object_from_file('remote.txt', 'local.txt')


上传网络流

  1. import requests
  2. input = requests.get('http://www.aliyun.com')
  3. bucket.put_object('aliyun.txt', input)

requests.get返回的是一个可迭代对象(iterable),此时Python SDK会通过Chunked Encoding方式上传。

返回值

  1. result = bucket.put_object('remote.txt', 'content of object')
  2. print('http status: {0}'.format(result.status))
  3. print('request_id: {0}'.format(result.request_id))
  4. print('ETag: {0}'.format(result.etag))
  5. print('date: {0}'.format(result.headers['date']))

每个OSS服务器返回的响应都有共同属性:
  • status:HTTP返回码
  • request_id:请求ID
  • headers:HTTP响应头部

etag则是put_object返回值特有的属性。

注意
  • 请求ID唯一标识了一次请求,强烈建议把它作为程序日志的一部分


小结


从上面的示例可以发现,Python SDK上传方法可以接受多种类型的输入源,这主要得益于第三方的requests库。小结一下,输入数据(data参数)可以有如下几种类型:
  • bytes字符串
  • unicode字符串:自动转换为UTF-8编码的bytes进行上传
  • 文件对象(file object):必须以二进制方式打开(如”rb”模式)
  • 可迭代对象(iterable):以Chunked Encoding的方式上传

注意:
  • 对于文件对象,如果是可以seek和tell的,那么会从文件当前位置开始上传,直到文件结束。


断点续传


当需要上传的本地文件很大,或网络状况不够理想,往往会出现上传到中途就失败了。此时,如果对已经上传的数据重新上传,既浪费时间,又占用了网络资源。Python SDK提供了一个易用性接口 oss2.resumable_upload ,用于断点续传本地文件:
  1. oss2.resumable_upload(bucket, 'remote.txt', 'local.txt')

其内部实现是当文件长度大于或等于可选参数 multipart_threshold 时,就进行分片上传。此时,会在HOME目录下建立.py-oss-upload目录,并把当前进度保存在其下的某个文件中。用户也可以通过可选参数store来指定保存进度的目录。
下面是一个完全定制化的例子:
  1. oss2.resumable_upload(bucket, 'remote.txt', 'local.txt',
  2.     store=oss2.ResumableStore(root='/tmp'),
  3.     multipart_threshold=100*1024,
  4.     part_size=100*1024,
  5.     num_threads=4)

含义是
  • ResumableStore 指定把进度保存到 /tmp/.py-oss-upload 目录下
  • multipart_threshold 指明只要文件长度不小于100KB就进行分片上传
  • part_size 参数建议每片大小为100KB。如果文件太大,那么分片大小也可能会大于100KB
  • num_threads 参数指定并发上传线程数为4

注意:
  • 请把 oss2.defaults.connection_pool_size 设成大于或等于线程数。
  • 要求 2.1.0 及以后版本






展开
收起
青衫无名 2017-10-18 11:29:37 2732 0
0 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
From Python Scikit-Learn to Sc 立即下载
一个跨平台的云服务SDK需要什么 立即下载
Data Pre-Processing in Python: 立即下载