Jul*_*lio 4 python python-2.7 python-3.x
我正在尝试通过套接字接收一系列 protobuf;我不会提前知道数据量。我发送了相当数量的消息,并且需要在收到消息时缓冲它们(以确保我收到所有消息)。我想利用 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:]
Run Code Online (Sandbox Code Playgroud)
是否可以使用 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:]
Run Code Online (Sandbox Code Playgroud)
当我尝试在末尾添加更多数据时,问题就出现了。如果我“偏移”现有视图,视图的大小就会“缩小*”,我可以添加越来越少的数据。是否有办法重用现有的内存视图并将数据向左移动?
*根据文档,我知道我无法调整数组的大小。我认为缩小的错觉是我的一个误解。
老实说,您不需要提前知道需要多少数据,只需继续阅读,直到不再获得任何数据为止:
import socket, sys
HOST = 'localhost' # The remote host
PORT = 50007 # The same port as used by the server
recvbuff = bytearray(16)
recvview = memoryview(recvbuff)
size = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
while True:
nbytes = s.recv_into(recvview)
if not nbytes:
break
size += nbytes
recvview = recvview[nbytes:]
if not len(recvview):
print "filled a chunk", recvbuff
recvview = memoryview(recvbuff)
print 'end of data', recvbuff[:len(recvview)], size
s.close()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4162 次 |
| 最近记录: |