此线程中的其他答案与 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)
但是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)
在谷歌搜索时,我还看到了一些可以使用的链接,但我没有尝试过: