该线程中的其他答案与 boto 相关,但 S3.Object 在 boto3 中不再可迭代。所以,下面的代码不起作用,它会产生一个TypeError: 's3.Object' object is not iterable
错误信息:
s3 = boto3.session.Session(profile_name=my_profile).resource('s3')
s3_obj = s3.Object(bucket_name=my_bucket, key=my_key)
with io.FileIO('sample.txt', 'w') as file:
for i in s3_obj:
file.write(i)
在 boto3 中,对象的内容位于S3.Object.get()['Body']
这是一个可迭代的版本1.9.68但以前不是。因此,以下内容适用于最新版本的 boto3,但不适用于早期版本:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body:
file.write(i)
因此,旧 boto3 版本的替代方法是使用 read 方法,但这会将整个 S3 对象加载到内存中,而在处理大文件时并不总是可行:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for i in body.read():
file.write(i)
But the read
方法允许传入amt
参数指定我们要从底层流读取的字节数。可以重复调用此方法,直到读取整个流:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
while file.write(body.read(amt=512)):
pass
深入挖掘botocore.response.StreamingBody
代码一意识到底层流也是可用的,因此我们可以按如下方式迭代:
body = s3_obj.get()['Body']
with io.FileIO('sample.txt', 'w') as file:
for b in body._raw_stream:
file.write(b)
在谷歌搜索时,我也看到了一些可以使用的链接,但我还没有尝试过:
- 包裹流体
- 另一个相关主题
-
boto3 github 中请求 StreamingBody 是正确流的问题- 已经关闭了!