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

Ped*_*eck 23 python amazon-s3 boto

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

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

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

Ste*_*pel 23

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

这是正确的,这是很容易的对象/文件大于5 GB的一个方式做PUT对象-复制操作,随后删除对象的操作(这两者在支持博托当然,看到copy_key()delete_key( )):

PUT操作的此实现创建已存储在Amazon S3中的对象的副本.PUT复制操作与执行GET然后执行PUT相同.添加请求标头x-amz-copy-source使PUT操作将源对象复制到目标存储桶中.

但是,对于大于5 GB的对象/文件,这确实是不可能的:

注意
[...]使用此API在单个原子操作中创建最大为5 GB的对象副本.但是,要复制大于5 GB的对象,必须使用分段上传API.对于概念信息[...],请转到使用分段上传 [...] [强调我的] 上传对象

Boto同时也通过copy_part_from_key()方法支持这一点; 遗憾的是,所需的方法没有记录在相应的拉取请求#425之外(允许多部分复制命令)(尽管我自己还没有尝试过):

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()
Run Code Online (Sandbox Code Playgroud)

您可能希望研究如何在Java或.NET中实现此目的的相应示例,这可能提供对常规方法的更多了解,请参阅 使用Multipart Upload API复制对象.

祝好运!


附录

请注意以下有关复制的特性,这很容易被忽视:

复制对象时,可以保留大部分元数据(默认)或指定新元数据.但是,ACL不会被保留,并且对于发出请求的用户而言设置为私有.要覆盖默认ACL设置,请在生成复制请求时使用x-amz-acl标头指定新ACL.有关更多信息,请参阅Amazon S3 ACL.[强调我的]

  • 现在记录下来了!http://boto.readthedocs.org/en/latest/ref/s3.html#module-boto.s3.multipart并且应该注意到最后一个块中的最后一个字节应该是文件大小 - 1,要关闭任何一个一个错误. (3认同)
  • 旧帖子,我知道,但 AWS/boto3 现在支持一个简单的副本 (S3.Client.copy),必要时内置多部分。请参阅 http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.copy 感谢您在这里的原始回复! (3认同)
  • 很好的答案和感谢指出这没有记录.我创建了一个跟踪此问题的问题:https://github.com/boto/boto/issues/729 (2认同)

小智 10

以上是非常接近工作,不幸的是应该结束mp.complete_upload() 而不是错字upload_complete()!

我在这里添加了一个有效的boto s3多部分副本脚本,基于AWS Java示例并使用5 GiB以上的文件进行测试:

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