我正在使用boto3
客户端的upload_fileobj
函数测试从 pythonglue
shell 作业写入S3
的吞吐量。 此函数的输入为
Fileobj (类似文件的对象) -- 要上传的类似文件的对象。在 最小值,它必须实现 Read 方法,并且必须返回字节。
为了使测试仅隔离吞吐量,而不是内存或CPU功能,我认为使用upload_file_object的最佳方法是传递一个iterator
,该产生0
N
字节的值。
在python中,如何从迭代器创建"类似文件的对象"?
我正在寻找某种形式
from itertools import repeat
number_of_bytes = 1024 * 1024
zero_iterator = repeat(b'0', number_of_bytes)
file_like_object = something(zero_iterator) # fill in 'something'
然后将其传递给 boto3 进行写入
session.client('s3').upload_fileobj(file_like_object, Bucket='my_bucket')
提前感谢您的考虑和回复。
这是 https://stackoverflow.com/a/70547492/1319998 答案的简化版本,因为我们只需要处理bytes
,因此应该适合 boto3 的upload_fileobj
def to_file_like_obj(iterable):
chunk = b''
offset = 0
it = iter(iterable)
def up_to_iter(size):
nonlocal chunk, offset
while size:
if offset == len(chunk):
try:
chunk = next(it)
except StopIteration:
break
else:
offset = 0
to_yield = min(size, len(chunk) - offset)
offset = offset + to_yield
size -= to_yield
yield chunk[offset - to_yield:offset]
class FileLikeObj:
def read(self, size=-1):
return b''.join(up_to_iter(float('inf') if size is None or size < 0 else size))
return FileLikeObj()
如果你有一个产生字节的迭代对象,my_iterable
说,这可以与 boto3 一起使用,如下所示:
target_obj = boto3.Session().resource('s3').Bucket('my-target-bucket').Object('my/target/key')
target_obj.upload_fileobj(to_file_like_obj(my_iterable)))