2013-04-12 17 views
7

Robię niektóre gniazdo IO i przy użyciu obiektu bytearray jako bufora. Chciałbym otrzymać dane z przesunięciem do tego bufora przy użyciu csock.recv_into, jak pokazano poniżej, aby uniknąć tworzenia pośredniczących obiektów typu string. Niestety, wygląda na to, że nie można użyć tych tagów w ten sposób, a poniższy kod nie działa.przy użyciu bytearray z socket.recv_into

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

Zamiast więc używam poniższy kod, który ma użyć tymczasowego ciąg (i działa) ...

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

Czy jest bardziej eleganckim sposobem na to, że nie robi”zrobić t wymagają skopiowania pośrednich ciągów wokół?

+0

Co to jest błąd otrzymujesz? Którą wersję Python używasz (dokładnie)? http://bugs.python.org/issue7827 sugeruje, że jest to poprawione w Pythonie 2.7.2. – nneonneo

+0

wersja python to 2.7.3. I nie jest to związane z tym błędem ... csock.recv_into (buf) działa dobrze dla mnie. Nie można tego użyć w następujący sposób: csock.recv_into (buf [read:]), ponieważ oryginalny obiekt buf nie jest aktualizowany. – cyann

Odpowiedz

18

Użyj memoryview aby owinąć bytearray:

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

Idealny! Dokładnie tego, czego szukałem, dzięki. Nie wiedziałem o pamięciach ... Czytałem je teraz! – cyann

Powiązane problemy