2013-04-12 23 views
7

Ich mache einige Socket IO, und mit einem Bytearray-Objekt als Puffer. Ich würde gerne Daten mit einem Offset in diesen Puffer mit csock.recv_into erhalten, wie unten gezeigt, um zu vermeiden, intermediäre String-Objekte zu erstellen. Leider scheint es, dass Bytearrays auf diese Weise nicht verwendet werden können und der folgende Code funktioniert nicht.mit Bytearray mit socket.recv_into

buf = bytearray(b" " * toread) 
read = 0 
while(toread): 
    nbytes = csock.recv_into(buf[read:],toread) 
    toread -= nbytes 
    read += nbytes 

Anstatt also ich den Code verwenden, die eine temporäre Zeichenfolge nicht verwendet (und Werke) ...

buf = bytearray(b" " * toread) 
read = 0 
while(toread): 
    tmp = csock.recv(toread) 
    nbytes = len(tmp) 
    buf[read:] = tmp 
    toread -= nbytes 
    read += nbytes 

Gibt es eine elegantere Möglichkeit, dies zu tun, die ‚doesn t müssen Sie Zwischenstrings kopieren?

+0

Was ist der Fehler, den Sie bekommen? Welche Version von Python benutzt du (genau)? http://bugs.python.org/issue7827 schlägt vor, dass dies ab Python 2.7.2 behoben ist. – nneonneo

+0

Python-Version ist 2.7.3. Und das hängt nicht mit diesem Fehler zusammen ... csock.recv_into (buf) funktioniert ganz gut für mich. Was nicht möglich ist, ist es so zu verwenden: csock.recv_into (buf [read:]), da dann das ursprüngliche buf-Objekt nicht aktualisiert wird. – cyann

Antwort

18

ein memoryview Verwenden Sie Ihre bytearray wickeln:

buf = bytearray(toread) 
view = memoryview(buf) 
while toread: 
    nbytes = sock.recv_into(view, toread) 
    view = view[nbytes:] # slicing views is cheap 
    toread -= nbytes 
+0

Perfekt! Genau das, was ich gesucht habe, danke. Wusste nicht über Memoryviews ... Lesen Sie jetzt darüber nach! – cyann