相当于boto3中的get_contents_to_file

时间:2016-02-01 17:10:05

标签: python amazon-s3 boto3

在boto3中,是否有等价的get_contents_to_file,它将对象的内容复制到文件句柄中?

在boto中,如果我有一个S3对象key,我可以将内容复制到一个临时文件中:

from tempfile import TemporaryFile
key = code_that_gets_key()

with TemporaryFile() as tmp_file:
    key.get_contents_to_file(key, tmpfile)

我还没找到boto3中的等价物。

我已将get_contents_to_filename的使用替换为download_file。但是,这涵盖了我提供文件名的情况。在这种情况下,我想提供文件句柄作为参数。

目前,我可以通过迭代主体来获取代码在boto3中工作,如下所示:

with TemporaryFile() as tmp_file:
    body = key.get()['Body']
    for chunk in iter(lambda: body.read(4096), b''):
        filehandle.write(chunk)

在boto3中有更好的方法吗?

4 个答案:

答案 0 :(得分:10)

V1.4.0开始,有一个download_fileobj函数可以完全按照您的要求执行操作。根据正式文件:

import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')
obj = bucket.Object('mykey')

with open('filename', 'wb') as data:
    obj.download_fileobj(data)

此操作也可在bucket resources3 client上使用,例如:

import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('mybucket')

with open('filename', 'wb') as data:
    bucket.download_fileobj('mykey', data)

答案 1 :(得分:1)

正确的答案是使用NamedTemporaryFile而不是TemporaryFile:

with NamedTemporaryFile() as tmp_file:
    file_name = tmp_file.name # This is what you are looking for

此处有更多文档:https://docs.python.org/2/library/tempfile.html

答案 2 :(得分:0)

彼得的回答是正确的,但我想指出,目前大部分AWS都没有部署boto3 1.4,最值得注意的是AWS Lambda。

这并不能阻止您动态升级,但如果您在新安装时运行代码,请务必检查

boto3.__version__ >= '1.4.0'

如果没有,请升级库。希望这很快就能解决,这将没有实际意义。

答案 3 :(得分:0)

请注意最受好评的答案。

get_contents_to_file download_fileobj 并不完全相同。

get_contents_to_file 可以将s3中的多个文件附加到单个文件对象。 download_fileobj 无法将s3中的多个文件附加到单个文件对象。

仅当您将单个s3文件添加到单个文件对象时,它们的作用相同。

示例:

def download_files(self, s3_key_list, f):
    for s3_key, in s3_key_list:
        s3_key_object = self.s3_hook.get_key(s3_key, self.s3_bucket)
        s3_key_object.get_contents_to_file(f)  # append all the s3 files to a single file object

def download_files(self, s3_key_list, f):
    for s3_key, in s3_key_list:
        s3_key_object = self.s3_hook.get_key(s3_key, self.s3_bucket)
        s3_key_object.download_fileobj(f)  # unable to do that, it overwrites the object, you have to use a for loop.