问题 相当于boto3中的get_contents_to_file


在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中有更好的方法吗?


10007
2018-02-01 17:10


起源

你不能通过 tmp_file.name 至 download_file() ? - helloV
@helloV在这种情况下,我可以使用 NamedTemporaryFile,有文件名。我不确定这是不是一个好主意,因为 download_file 方法将为同一个文件打开一个新的文件句柄。通常,并非所有文件句柄都具有文件名(例如, StringIO, TemporaryFile)。 - Alasdair
这不是什么 download_fileobj 是为了? - Peter Brittain
@PeterBrittain是的, download_fileobj 正是我正在寻找的。看起来它是1.4版本中的新功能。 - Alasdair


答案:


作为 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)

该操作也可在 桶资源 和 s3客户端 同样,例如:

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

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

10
2017-08-08 22:53



哎呀,应该是 s3 = boto3.resource('s3')。 Mea culpa,文档应该很快更新。值得注意的是,此操作可在此处使用 s3客户端 和 对象资源 同样。 - Jordon Phillips
@JordonPhillips谢谢!在做摘录时我觉得我应该注意到...... - Peter Brittain
谢谢Peter和@JordonPhillips。就我而言,它是我特意寻找的对象版本。 - Alasdair


正确的答案是使用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


0
2017-08-08 19:31



这适用于我给出的示例,但它不是我正在寻找的一般解决方案。正如我在评论中所说,并非所有文件句柄都有文件名。 - Alasdair


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

这并不妨碍您即时升级,但如果您在全新安装上运行代码,请务必检查

boto3.__version__ >= '1.4.0'

如果没有,请升级库。希望这将很快修复,这将没有实际意义。


0
2017-08-30 21:23