import io
import boto3
client = boto3.client('s3')
buffer = io.BytesIO()
# This is just an example, parameters should be fine tuned according to:
# 1. The size of the object that is being read (bigger the file, bigger the chunks)
# 2. The number of threads available on the machine that runs this code
config = TransferConfig(
multipart_threshold=1024 * 25, # Concurrent read only if object size > 25MB
max_concurrency=10, # Up to 10 concurrent readers
multipart_chunksize=1024 * 25, # 25MB chunks per reader
use_threads=True # Must be True to enable multiple readers
)
# This method writes the data into the buffer
client.download_fileobj(
Bucket=bucket_name,
Key=object_key,
Fileobj=buffer,
Config=config
)
str_value = buffer.getvalue().decode()
8条答案
按热度按时间mznpcxlj1#
read
将返回字节。至少对于Python 3,如果你想返回一个字符串,你必须使用正确的编码进行解码:5jvtdoz22#
我在从S3读取/解析对象时遇到了问题,因为
.get()
在AWS Lambda中使用Python 2.7。我在示例中添加了json,以显示它变得可解析:)
注意(对于python 2.7):我的对象都是ascii,所以我不需要
.decode('utf-8')
注意(对于Python 3):我们转到python 3,发现
read()
现在返回bytes
,所以如果你想从它得到一个字符串,你必须用途:j = json.loads(obj['Body'].read().decode('utf-8'))
ohtdti5x3#
boto3的文档中没有这一点。这对我很有效:
对象是s3对象:http://boto3.readthedocs.org/en/latest/reference/services/s3.html#object
f0brbegy4#
Python3 +使用boto3 API的方法。
通过S3.Client.download_fileobj API和Python类文件对象,可以将S3 Object内容检索到内存中。
由于检索到的内容是字节,为了转换为str,需要对其进行解码。
tuwxkamq5#
将整个对象体解码为一个字符串:
将对象体逐行解码为字符串:
自Python 3以来,bytes的
decode()
中的默认编码已经是'utf-8'
。当解码为JSON时,不需要转换为字符串,因为json.loads也接受字节,因为Python 3.6:
kb5ga3dv6#
最快方法
正如这里的文档所述,
download_fileobj
使用并行化:这是一个托管传输,如果需要,它将在多个线程中执行多部分下载。
报价aws documentation:
通过在GetObjectRequest中指定部件号,可以从S3检索对象的一部分。TransferManager使用此逻辑异步下载对象的所有部件,并将它们写入单个临时文件。然后,临时文件将合并到用户提供的目标文件中。
这可以利用将数据保存在内存中而不是将其写入文件中。
@Gatsby Lee
所展示的方法可以做到这一点,这就是为什么它是列出的那些方法中最快的。无论如何,它可以使用Config
参数进行更多改进:对于大于1GB的对象,在速度方面已经是值得的了。
pes8fvy97#
类型为〈class 'botocore.response. StreamingBody'〉
当你打电话
您正在访问StreamingBody对象,它将S3对象的内容表示为流。这允许您以块的形式读取数据并增量处理它。
另一方面,当你调用s3.get_object(Bucket=bucket_name,Key=s3_key)[“Body”].read()时,你将把对象的全部内容读入内存,并以bytes对象的形式返回。如果对象很大,这是没有效率的,因为它会很快消耗大量内存。
vhipe2zx8#
如果body包含一个io.StringIO,你必须像下面这样做: