如何使用boto3将S3对象保存到文件中
我试图用新的boto3客户端来做一个“hello world”。
我使用的用例很简单:从S3获取对象并将其保存到文件中。
在博托2.XI会这样做:
import boto key = boto.connect_s3().get_bucket('foo').get_key('foo') key.get_contents_to_filename('/tmp/foo')
在博托3。 我无法find一个干净的方式来做同样的事情,所以我手动迭代“stream”对象:
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)
它工作正常。 我想知道是否有任何“本地”boto3function,将执行相同的任务?
有一个最近进入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())
这些function将自动处理读取/写入文件以及对大文件并行进行分段上传。
boto3现在拥有比客户更好的界面:
resource = boto3.resource('s3') my_bucket = resource.Bucket('MyBucket') my_bucket.download_file(key, local_filename)
在接受的答案中,这本身并不比client
好得多(尽pipe文档说它在重试失败时重试上传和下载效果更好),但考虑到资源通常更符合人体工程学(例如,s3 存储桶和对象资源比客户端方法更好),这可以让你留在资源层,而不必下拉。
Resources
通常可以像客户一样创build,他们采取全部或大部分相同的论点,并将其转发给内部客户。
对于那些想要模拟像boto2方法那样的set_contents_from_string的人,可以试试
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())
# Preface: File is json with contents: {'name': 'Android', 'status': 'ERROR'} import boto3 import io s3 = boto3.resource( 's3', aws_access_key_id='my_access_id', aws_secret_access_key='my_secret_key' ) obj = s3.Object('my-bucket', 'key-to-file.json') data = io.BytesIO() obj.download_fileobj(data) # object is now a bytes string, Converting it to a dict: new_dict = json.loads(data.getvalue().decode("utf-8")) print(new_dict['status']) # Should print "Error"