【发布时间】:2014-05-14 16:49:17
【问题描述】:
我正在尝试通过套接字接收一系列 protobuf;我不会提前知道数据量。我正在发送相当数量的邮件,并且在收到邮件时需要buffer the messages(以确保我收到所有邮件)。我想利用 Python 中可用的 bytearray/memoryview 来消除不必要的副本。
我目前正在使用字符串并在收到数据时附加数据。这很容易,我可以通过执行以下操作“转移”“缓冲区”:
# Create the buffer
str_buffer = []
# Get some data and add it to our "buffer"
str_buffer += "Hello World"
# Do something with the data . . .
# "shift"/offset the message by the data we processed
str_buffer = str_buffer[6:]
是否可以使用 bytearray/memoryview 做类似的事情?
# Create the buffer/memoryarray
buffer = bytearray(1024)
view = memoryview(buffer)
# I can set a single byte
view[0] = 'a'
# I can "offset" the view by the data we processed, but doing this
# shrinks the view by 3 bytes. Doing this multiple times eventually shrinks
# the view to 0.
view = view[3:]
当我尝试在末尾添加更多数据时出现问题。如果我曾经“偏移”现有视图,视图的大小会“缩小*”,我可以添加越来越少的数据。有没有办法重用现有的内存视图并将数据向左移动?
*根据文档,我知道我无法调整数组的大小。我认为缩小的错觉是我的误解。
【问题讨论】:
-
我已经找到那个帖子了。答案的前提是预先知道数据量。因此,您可以在开始接收数据之前分配适当大小的字节数组。它没有提到重用(小)固定大小的字节数组/内存视图。
-
您无需提前知道发送者将发送多少数据以使用
recv_from()。它总是返回它得到的字节数;如果这是您的memoryview的大小,那么还有更多数据需要,请再次致电recv_from()。 -
在您提到的示例中,
toread是在 while 循环之外定义的。recv_into返回读取的数据量,是的。数据量从toread中减去,直到为0。这似乎表明toread的数据量是事先已知的,用于创建适当大小的字节数组。我错过了什么吗?
标签: python python-2.7 python-3.x