当前位置: 首页 > 知识库问答 >
问题:

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

尹正奇
2023-03-14

亚马逊S3 REST API文档称上传操作的上传大小限制为5gb。大于该值的文件必须使用multipart上传。好吧。

然而,我本质上需要的是重命名可能比那个更大的文件。据我所知,没有重命名或移动操作,因此我必须将文件复制到新位置并删除旧文件。对于大于5gb的文件,具体是如何做到的呢?我必须从存储桶向自身进行多部分上传?在这种情况下,如何将文件分成几部分呢?

从阅读boto的源代码来看,它似乎并没有自动为大于5gb的文件执行此类操作。是否有任何我错过的内置支持?

共有3个答案

汪丁雷
2023-03-14

我发现这种方法可以上传大于5g的文件,并将其修改为使用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()
薛枫
2023-03-14

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

我在这里添加了一个可工作的boto s3多部分拷贝脚本,该脚本基于AWS Java示例,并使用超过5GiB的文件进行了测试:

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

袁建木
2023-03-14

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

没错,对于小于5 GB的对象/文件,通过PUT Object-Copy操作,然后是DELETE Object操作(当然,boto中都支持这两种操作,请参见Copy_key()和DELETE_key

这个PUT操作的实现创建了一个已经存储在亚马逊S3中的对象的副本。PUT copy操作与先执行GET再执行PUT操作相同。添加请求头x-amz-copy-source使PUT操作将源对象复制到目的地bucket中。

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

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

Boto同时也通过copy_part_from_key()方法支持这一点;不幸的是,所需的方法没有记录在相应的pull request #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()

您可能希望研究最终如何在Java或.NET中实现这一点的各个示例,这可能会对一般方法有更多的了解,请参阅使用Multipart Upload API复制对象。

祝你好运!

请注意以下关于复制的特点,这很容易被忽略:

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

 类似资料:
  • 我正在尝试使用EMR中的工作流将文件从s3复制到hdfs,当我运行以下命令时,jobflow成功启动,但当它尝试将文件复制到HDFS时给我一个错误。我需要设置任何输入文件权限吗? 命令: ./elastical mapreduce--作业流j-35D6JOYEDCELA--jar s3://us-east-1.elasticmapreduce/libs/s3distcp/1.latest/s3di

  • 我正在尝试安装和配置nginx,但我需要复制一个完整的配置文件。我尝试简单地将它添加到Dockerfile中,因为它只有几行,但Dockerfile似乎对多行命令没有很好的支持。我的意思是我需要复制我的配置文件的原样,我不能污染它的'sed','cat'或'\'在每一行。 有些人建议将配置文件放在公共git存储库中,我想如果没有其他方法的话,我可以这么做。但我一点也不喜欢,因为这没道理。我不想为这

  • 现在我正在编写一个maven依赖项a,并在项目B中使用这个依赖项。两者的文件结构都是: 依赖A: 项目B: 我想做的是当我运行mvn spring boot时:在项目B中运行,测试。A的src/main/resources/files中的txt将被复制到项目B的/WebContent中。 我尝试在依赖项A中编写以下代码: 但是当我执行mvn spring boot:run时,它说文件不存在。

  • 我有一个图像缓存在我的应用程序文档文件夹。我想把它复制到文档文件夹里。到目前为止,我知道我可以加载我的图像作为UIIimage,然后将它转换为数据并保存在我的目标路径中。但有没有比这更好的办法呢?就像我不想在UIIimage中转换我的图像,然后再将其转换为数据并写入。 我的png代码是:

  • 我想知道一种干净和通用的方法来实现这一点,只使用CSS超文本标记语言。最小的标记/黑客攻击是可取的。 目标是提供一个工作示例,其中: 有一个任意大小的父容器盒 到目前为止,这是一种丑陋的方法:

  • 进程无法访问文件'd:\app_data\',因为另一个进程正在使用它。 这是我一直在用的代码