断点续传复制适用于通过 TOS Python SDK 在单个桶内或同区域的两个桶之间复制大对象的场景。TOS Python SDK 提供了断点续传下载的功能,借助本地 CheckPoint 的机制记录已成功复制的分段,当出现网络异常或机器故障等问题导致分段复制中断,可再次调用该接口以实现续传的效果。断点续传复制将待复制的对象分割为多个分段,并支持并发复制,待所有分段复制完成后,合并成完整的文件。您可以设置断点续传复制的分段大小、复制分段的线程数、事件回调函数等。同时也能在断点续传复制任务执行过程中,取消该任务。
以下代码用于断点续传拷贝 src_bucket_name
桶中 src_object_key
对象到 bucket_name
桶中,并设置对象对象名为 object_key
以及失败后重入下载。若复制过程中返回网络超时的报错,则您可以以相同参数调用 resumable_copy_object
后实现断点续传下载重入。
import os import tos # 从环境变量获取 AK 和 SK 信息。 ak = os.getenv('TOS_ACCESS_KEY') sk = os.getenv('TOS_SECRET_KEY') # your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。 endpoint = "your endpoint" region = "your region" # 目标桶的名称 bucket_name = "bucket-test" # 拷贝到目标桶后的对象名称 object_key = "object-test" # 源桶的名称 src_bucket_name = "your src bucket name" # 源对象的名称 src_object_key = "your src object key" try: # 创建 TosClientV2 对象,对桶和对象的操作都通过 TosClientV2 实现 client = tos.TosClientV2(ak, sk, endpoint, region) client.resumable_copy_object(bucket_name, object_key, src_bucket_name, src_object_key, # 通过task num配置并发线程数, task_num=3, # 通过part_size配置分片大小 part_size=20 * 1024 * 1024) except tos.exceptions.TosClientError as e: # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常 print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause)) except tos.exceptions.TosServerError as e: # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息 print('fail with server error, code: {}'.format(e.code)) # request id 可定位具体问题,强烈建议日志中保存 print('error with request id: {}'.format(e.request_id)) print('error with message: {}'.format(e.message)) print('error with http code: {}'.format(e.status_code)) print('error with ec: {}'.format(e.ec)) print('error with request url: {}'.format(e.request_url)) except Exception as e: print('fail with unknown error: {}'.format(e))
以下代码用于自定义断点续传拷贝回调函数。
import os import tos from tos import CopyEventType # 从环境变量获取 AK 和 SK 信息。 ak = os.getenv('TOS_ACCESS_KEY') sk = os.getenv('TOS_SECRET_KEY') # your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。 endpoint = "your endpoint" region = "your region" # 目标桶的名称 bucket_name = "bucket-test" # 拷贝到目标桶后的对象名称 object_key = "object-test" # 源桶的名称 src_bucket_name = "your src bucket name" # 源对象的名称 src_object_key = "your src object key" try: # 创建 TosClientV2 对象,对桶和对象的操作都通过 TosClientV2 实现 def copy_event(copy_event_type: CopyEventType, err, bucket, key, upload_id, src_bucket, src_key, src_version_id, checkpoint, copy_part): print(copy_event_type, err, bucket, key, upload_id, src_bucket, src_key, src_version_id, checkpoint, copy_part) client = tos.TosClientV2(ak, sk, endpoint, region) client.resumable_copy_object(bucket_name, object_key, src_bucket_name, src_object_key, # 通过task num配置并发线程数, task_num=3, # 通过part_size配置分片大小 part_size=20 * 1024 * 1024, copy_event_listener=copy_event) except tos.exceptions.TosClientError as e: # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常 print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause)) except tos.exceptions.TosServerError as e: # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息 print('fail with server error, code: {}'.format(e.code)) # request id 可定位具体问题,强烈建议日志中保存 print('error with request id: {}'.format(e.request_id)) print('error with message: {}'.format(e.message)) print('error with http code: {}'.format(e.status_code)) print('error with ec: {}'.format(e.ec)) print('error with request url: {}'.format(e.request_url)) except Exception as e: print('fail with unknown error: {}'.format(e))
以下代码用于暂停或取消断点续传拷贝任务。
import time from threading import Thread import os import tos from tos import CopyEventType from tos.checkpoint import CancelHook # 从环境变量获取 AK 和 SK 信息。 ak = os.getenv('TOS_ACCESS_KEY') sk = os.getenv('TOS_SECRET_KEY') # your endpoint 和 your region 填写Bucket 所在区域对应的Endpoint。# 以华北2(北京)为例,your endpoint 填写 tos-cn-beijing.volces.com,your region 填写 cn-beijing。 endpoint = "your endpoint" region = "your region" # 目标桶的名称 bucket_name = "bucket-test" # 拷贝到目标桶后的对象名称 object_key = "object-test" # 源桶的名称 src_bucket_name = "your src bucket name" # 源对象的名称 src_object_key = "your src object key" try: # 继承 CancelHook 类实现断点续传下载任务取消功能 class MyCancel(CancelHook): def cancel(self, is_abort: bool): # is_abort 为 true 时删除上下文信息并 abort 分段上传任务,为 false 时只是中断当前执行 # 重写 cancel 方法时必须调用 父类的 cancel 方法 # 模拟 10 秒后取消任务 time.sleep(10) super(MyCancel, self).cancel(is_abort=is_abort) print('some user define') cancel = MyCancel() t1 = Thread(target=cancel.cancel, args=(False,)) t1.start() client = tos.TosClientV2(ak, sk, endpoint, region) client.resumable_copy_object(bucket_name, object_key, src_bucket_name, src_object_key, # 通过task num配置并发线程数, task_num=3, # 通过part_size配置分片大小 part_size=20 * 1024 * 1024, cancel_hook=cancel) except tos.exceptions.TosClientError as e: # 操作失败,捕获客户端异常,一般情况为非法请求参数或网络异常 print('fail with client error, message:{}, cause: {}'.format(e.message, e.cause)) except tos.exceptions.TosServerError as e: # 操作失败,捕获服务端异常,可从返回信息中获取详细错误信息 print('fail with server error, code: {}'.format(e.code)) # request id 可定位具体问题,强烈建议日志中保存 print('error with request id: {}'.format(e.request_id)) print('error with message: {}'.format(e.message)) print('error with http code: {}'.format(e.status_code)) print('error with ec: {}'.format(e.ec)) print('error with request url: {}'.format(e.request_url)) except Exception as e: print('fail with unknown error: {}'.format(e))