OSS有多种上传方式,不同的上传方式能够上传的数据大小也不一样。普通上传(PutObject)、追加上传(AppendObject)最多只能上传小于或等于5GB的文件;而分片上传每个分片可以达到5GB,合并后的文件能够达到48.8TB。
首先介绍普通上传,我们会详细展示提供数据的各种方式,即方法中的 data 参数。其他上传接口有类似的data参数,不再赘述。
普通上传
通过 Bucket.put_object 方法,可以上传一个普通文件。
上传字符串
上传内存中的字符串:
- # -*- coding: utf-8 -*-
- import oss2
- auth = oss2.Auth('您的AccessKeyId', '您的AccessKeySecret')
- bucket = oss2.Bucket(auth, '您的Endpoint', '您的Bucket名')
- bucket.put_object('remote.txt', 'content of object')
也可以指定上传的是bytes:
- bucket.put_object('remote.txt', b'content of object')
或是指定为unicode:
- bucket.put_object('remote.txt', u'content of object')
事实上,oss2.Bucket.put_object的第二个参数(参数名为data)可以接受两种类型的字符串:
- bytes:直接上传
- unicode:会自动转换为UTF-8编码的bytes进行上传
上传本地文件
- with open('local.txt', 'rb') as fileobj:
- bucket.put_object('remote.txt', fileobj)
对比上传字符串的代码,注意到数据参数既可以是字符串,也可以是这里的文件对象(file object)。
注意:
- 必须以二进制的方式打开文件,因为内部实现需要知道文件包含的字节数。
Python SDK还提供了一个便捷的方法完成上面的工作:
- bucket.put_object_from_file('remote.txt', 'local.txt')
上传网络流
- import requests
- input = requests.get('http://www.aliyun.com')
- bucket.put_object('aliyun.txt', input)
requests.get返回的是一个可迭代对象(iterable),此时Python SDK会通过Chunked Encoding方式上传。
返回值
- result = bucket.put_object('remote.txt', 'content of object')
- print('http status: {0}'.format(result.status))
- print('request_id: {0}'.format(result.request_id))
- print('ETag: {0}'.format(result.etag))
- 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 ,用于断点续传本地文件:
- oss2.resumable_upload(bucket, 'remote.txt', 'local.txt')
其内部实现是当文件长度大于或等于可选参数 multipart_threshold 时,就进行分片上传。此时,会在HOME目录下建立.py-oss-upload目录,并把当前进度保存在其下的某个文件中。用户也可以通过可选参数store来指定保存进度的目录。
下面是一个完全定制化的例子:
- oss2.resumable_upload(bucket, 'remote.txt', 'local.txt',
- store=oss2.ResumableStore(root='/tmp'),
- multipart_threshold=100*1024,
- part_size=100*1024,
- 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 及以后版本