Amazon S3 REST API文档显示,在PUT操作中上传的大小限制为5gb。大于此的文件必须使用multipart上传。细
但是,我真正需要的是重命名可能比那些文件大的文件。据我所知,没有重命名或移动操作,因此我必须将文件复制到新位置并删除旧位置。如何使用大于5gb的文件完成这项工作?我必须从存储桶到自身进行分段上传吗?在这种情况下,如何拆分部分文件?
从阅读boto的源代码来看,对于大于5gb的文件,它似乎不会自动执行此类操作。我错过了任何内置支持吗?
答案 0 :(得分:23)
据我所知,没有重命名或移动操作,因此我有 将文件复制到新位置并删除旧文件。
这是正确的,对于小于5 GB的对象/文件,通过PUT Object - Copy操作,然后进行DELETE Object操作非常容易({{3}支持这两种操作)当然,请参阅boto和copy_key()):
PUT操作的这种实现创建了一个对象的副本 已存储在Amazon S3中。 PUT复制操作是相同的 执行GET然后执行PUT。添加请求标头, x-amz-copy-source,使PUT操作将源对象复制到 目的地桶。
但是,对于大于5 GB的对象/文件来说,这确实是不可能的:
注意强>
[...]您可以在单个原子中创建最大5 GB大小的对象副本 使用此API的操作。 但是,用于复制大于的对象 5 GB,您必须使用分段上传API 。对于概念 信息[...],转到delete_key() [...] [强调我的]
Boto同时也通过Uploading Objects Using Multipart Upload方法支持这一点;遗憾的是,所需的方法没有记录在相应的copy_part_from_key()之外(尽管我自己还没有尝试过):
import boto
s3 = boto.connect_s3('access', 'secret')
b = s3.get_bucket('destination_bucket')
mp = b.initiate_multipart_upload('tmp/large-copy-test.mp4')
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 1, 0, 999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 2, 1000000000, 1999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 3, 2000000000, 2999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 4, 3000000000, 3999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 5, 4000000000, 4999999999)
mp.copy_part_from_key('source_bucket', 'path/to/source/key', 6, 5000000000, 5500345712)
mp.complete_upload()
您可能希望研究有关如何在Java或.NET中实现此目的的相应示例,这可能会提供有关一般方法的更多信息,请参阅pull request #425 (allow for multi-part copy commands)。
祝你好运!请注意以下关于复制的一般特性,这很容易被忽视:
复制对象时,可以保留大部分元数据 (默认)或指定新元数据。 但是,不保留ACL 并且对于发出请求的用户设置为私人。要覆盖 默认ACL设置,使用x-amz-acl标头指定新ACL 生成复制请求时。有关更多信息,请参阅Amazon S3 访问控制列表。 [强调我的]
答案 1 :(得分:10)
上述内容非常接近工作,不幸的是应该以{{1}}结束
而不是拼写错误mp.complete_upload()
!
我在这里添加了一个有效的boto s3多部分副本脚本,基于AWS Java示例并使用超过5 GiB的文件进行测试:
答案 2 :(得分:1)
我发现这种方法可以上传大于5gigs的文件并修改它以使用Boto复制程序。 这是原作:http://boto.cloudhackers.com/en/latest/s3_tut.html
import math
from boto.s3.connection import S3Connection
from boto.exception import S3ResponseError
conn = S3Connection(host=[your_host], aws_access_key_id=[your_access_key],
aws_secret_access_key=[your_secret_access_key])
from_bucket = conn.get_bucket('your_from_bucket_name')
key = from_bucket.lookup('my_key_name')
dest_bucket = conn.get_bucket('your_to_bucket_name')
total_bytes = key.size
bytes_per_chunk = 500000000
chunks_count = int(math.ceil(total_bytes/float(bytes_per_chunk)))
file_upload = dest_bucket.initiate_multipart_upload(key.name)
for i in range(chunks_count):
offset = i * bytes_per_chunk
remaining_bytes = total_bytes - offset
print(str(remaining_bytes))
next_byte_chunk = min([bytes_per_chunk, remaining_bytes])
part_number = i + 1
file_upload.copy_part_from_key(dest_bucket.name, key.name, part_number,
offset, offset + next_byte_chunk - 1)
file_upload.complete_upload()
答案 3 :(得分:1)
现在标准的.copy
方法将对大于5GB的文件执行分段上传。 Official Docs
import boto3
s3 = boto3.resource('s3')
copy_source = {
'Bucket': 'mybucket',
'Key': 'mykey'
}
s3.meta.client.copy(copy_source, 'otherbucket', 'otherkey')