本文介绍如何将一个存储空间(源存储空间)中的文件复制到同一地域下相同或不同存储空间(目标存储空间)中。

拷贝文件时注意事项如下:

  • 用户必须有源Object的读权限及目标Bucket的读写权限。
  • 不支持跨地域拷贝。例如不能将华东1(杭州)地域存储空间中的文件拷贝到华北1(青岛)地域。

拷贝小文件

对于小于1 GB的文件,您可以使用简单拷贝。以下代码用于通过简单拷贝将源存储空间srcexamplebucket中的srcexampleobject.txt文件拷贝到目标存储空间destexamplebucket中的destexampleobject.txt文件。

# -*- coding: utf-8 -*-
import oss2

# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# 填写源Bucket名称,例如srcexamplebucket。
src_bucket_name = 'srcexamplebucket'
# 填写与源Bucket处于同一地域的目标Bucket名称,例如destexamplebucket。
# 当在同一Bucket内拷贝文件时,请确保源Bucket名称和目标Bucket名称相同。
dest_bucket_name = 'destexamplebucket'
# yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
bucket = oss2.Bucket(auth, 'yourEndpoint', dest_bucket_name)

# 填写源Object完整路径,例如srcexampleobject.txt。Object完整路径中不能包含Bucket名称。
src_object_name = 'srcexampleobject.txt'
# 填写目标Object完整路径,例如destexampleobject.txt。Object完整路径中不能包含Bucket名称。
dest_object_name = 'destexampleobject.txt'

# 从源Bucket中拷贝一个Object到目标Bucket。
result = bucket.copy_object(src_bucket_name, src_object_name, dest_object_name)

# 查看返回结果的状态,如果返回值为200时,表示执行成功。
print('result.status:', result.status)

关于拷贝小文件的更多信息,请参见CopyObject

拷贝大文件

对于大于1 GB的文件,需要使用分片拷贝(UploadPartCopy)。分片拷贝分为三步:

  1. 通过bucket.init_multipart_upload初始化分片拷贝任务。
  2. 通过bucket.upload_part_copy进行分片拷贝。除最后一个分片外,其它分片都要大于100 KB。
  3. 通过bucket.complete_multipart_upload提交分片拷贝任务。

以下代码用于通过分片拷贝将源存储空间srcexamplebucket中的srcexampleobject.txt文件拷贝到目标存储空间destexamplebucket中的destexampleobject.txt文件。

# -*- coding: utf-8 -*-
import oss2
from oss2.models import PartInfo
from oss2 import determine_part_size

# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
auth = oss2.Auth('yourAccessKeyId', 'yourAccessKeySecret')
# 填写源Bucket名称,例如srcexamplebucket。
src_bucket_name = 'srcexamplebucket'
# 填写与源Bucket处于同一地域的目标Bucket名称,例如destexamplebucket。
# 当在同一Bucket内拷贝文件时,请确保源Bucket名称和目标Bucket名称相同。
dest_bucket_name = 'destexamplebucket'
# yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
bucket = oss2.Bucket(auth, 'yourEndpoint', dest_bucket_name)
# 当在同一Bucket内拷贝文件时,请注释掉该行代码,并将后面的src_bucket改为bucket即可。
src_bucket = oss2.Bucket(auth, 'yourEndpoint', src_bucket_name)



# 填写源Object完整路径,例如srcexampleobject.txt。Object完整路径中不能包含Bucket名称。
src_object_name = 'srcexampleobject.txt'
# 填写目标Object完整路径,例如destexampleobject.txt。Object完整路径中不能包含Bucket名称。
dest_object_name = 'destexampleobject.txt'
# 获取指定版本的源文件的文件大小。当在同一Bucket内拷贝文件时,请将src_bucket改为bucket。
head_info = src_bucket.head_object(src_object_name)
total_size = head_info.content_length
print('src object size:', total_size)

# determine_part_size方法用来确定分片大小。
part_size = determine_part_size(total_size, preferred_size=100 * 1024)
print('part_size:', part_size)

# 初始化分片。
upload_id = bucket.init_multipart_upload(dest_object_name).upload_id
parts = []

# 逐个上传分片。
part_number = 1
offset = 0
while offset < total_size:
    num_to_upload = min(part_size, total_size - offset)
    end = offset + num_to_upload - 1
    result = bucket.upload_part_copy(src_bucket_name, src_object_name, (offset, end), dest_object_name, upload_id, part_number)
    # 保存part信息。
    parts.append(PartInfo(part_number, result.etag))

    offset += num_to_upload
    part_number += 1

# 完成分片拷贝。
result = bucket.complete_multipart_upload(dest_object_name, upload_id, parts)
# 查看拷贝返回状态。
print('result :', result.status)
# 获取文件元信息。
head_info = bucket.head_object(dest_object_name)
# 查看目标Object大小。
dest_object_size = head_info.content_length
print('dest object size:', dest_object_size)
# 对比源Object和目标Object的大小。
assert dest_object_size == total_size

关于分片拷贝的更多信息,请参见UploadPartCopy