如何使用boto3将S3对象保存到文件中

2024-04-29 05:28:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用AWS的新boto3客户机创建一个“hello world”。

我拥有的用例相当简单:从S3获取对象并将其保存到文件中。

在boto 2.X中,我会这样做:

import boto
key = boto.connect_s3().get_bucket('foo').get_key('foo')
key.get_contents_to_filename('/tmp/foo')

在博图3。我找不到一个干净的方法来做同样的事情,所以我在“Streaming”对象上手动迭代:

import boto3
key = boto3.resource('s3').Object('fooo', 'docker/my-image.tar.gz').get()
with open('/tmp/my-image.tar.gz', 'w') as f:
    chunk = key['Body'].read(1024*8)
    while chunk:
        f.write(chunk)
        chunk = key['Body'].read(1024*8)

或者

import boto3
key = boto3.resource('s3').Object('fooo', 'docker/my-image.tar.gz').get()
with open('/tmp/my-image.tar.gz', 'w') as f:
    for chunk in iter(lambda: key['Body'].read(4096), b''):
        f.write(chunk)

而且效果很好。我想知道有没有“原生”的boto3功能可以完成同样的任务?


Tags: keyimageimportreadgets3foomy
3条回答

有一个定制,最近进入Boto3有助于这一点(除其他外)。它当前在低级S3客户机上公开,可以如下使用:

s3_client = boto3.client('s3')
open('hello.txt').write('Hello, world!')

# Upload the file to S3
s3_client.upload_file('hello.txt', 'MyBucket', 'hello-remote.txt')

# Download the file from S3
s3_client.download_file('MyBucket', 'hello-remote.txt', 'hello2.txt')
print(open('hello2.txt').read())

这些函数将自动处理读/写文件,以及对大型文件并行执行多部分上载。

请注意,s3_client.download_file不会创建目录。它可以创建为pathlib.Path('/path/to/file.txt').parent.mkdir(parents=True, exist_ok=True)

boto3现在有了比客户端更好的接口:

resource = boto3.resource('s3')
my_bucket = resource.Bucket('MyBucket')
my_bucket.download_file(key, local_filename)

这本身并不比公认答案中的client好多少(尽管文档中说它在失败时重试上传和下载的工作做得更好),但是考虑到资源通常更符合人体工程学(例如,s3bucketobject资源比客户机方法更好)这确实允许您留在资源层而不必下拉。

^{}通常可以用与客户机相同的方式创建,它们接受所有或大部分相同的参数,并将它们转发给内部客户机。

对于那些想模拟类似于boto2方法的人,可以尝试

import boto3
from cStringIO import StringIO

s3c = boto3.client('s3')
contents = 'My string to save to S3 object'
target_bucket = 'hello-world.by.vor'
target_file = 'data/hello.txt'
fake_handle = StringIO(contents)

# notice if you do fake_handle.read() it reads like a file handle
s3c.put_object(Bucket=target_bucket, Key=target_file, Body=fake_handle.read())

对于Python3:

在Python3中都是StringIO and cStringIO are gone。使用StringIO导入方式如下:

from io import StringIO

要同时支持这两个版本:

try:
   from StringIO import StringIO
except ImportError:
   from io import StringIO

相关问题 更多 >