如何在Amazon S3中复制大于5 GB的文件?

时间:2012-04-27 18:29:22

标签: python amazon-s3 boto

Amazon S3 REST API文档显示,在PUT操作中上传的大小限制为5gb。大于此的文件必须使用multipart上传。细

但是,我真正需要的是重命名可能比那些文件大的文件。据我所知,没有重命名或移动操作,因此我必须将文件复制到新位置并删除旧位置。如何使用大于5gb的文件完成这项工作?我必须从存储桶到自身进行分段上传吗?在这种情况下,如何拆分部分文件?

从阅读boto的源代码来看,对于大于5gb的文件,它似乎不会自动执行此类操作。我错过了任何内置支持吗?

4 个答案:

答案 0 :(得分:23)

  

据我所知,没有重命名或移动操作,因此我有   将文件复制到新位置并删除旧文件。

这是正确的,对于小于5 GB的对象/文件,通过PUT Object - Copy操作,然后进行DELETE Object操作非常容易({{3}支持这两种操作)当然,请参阅botocopy_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的文件进行测试:

https://gist.github.com/joshuadfranklin/5130355

答案 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')