如何从迭代器创建类似 Python 文件的对象



我正在使用boto3客户端的upload_fileobj函数测试从 pythonglueshell 作业写入S3的吞吐量。 此函数的输入为

Fileobj (类似文件的对象) -- 要上传的类似文件的对象。在 最小值,它必须实现 Read 方法,并且必须返回字节。

为了使测试仅隔离吞吐量,而不是内存或CPU功能,我认为使用upload_file_object的最佳方法是传递一个iterator,该产生0N字节的值。

在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)))

最新更新