Buffer binario in Python
Domanda
In Python puoi usare StringIO per un buffer simile a un file per i dati dei caratteri. File mappato in memoria fondamentalmente fa una cosa simile per i dati binari, ma richiede un file utilizzato come base.Python ha un oggetto file destinato ai dati binari ed è solo memoria, equivalente a quello di Java ByteArrayOutputStream?
Il caso d'uso che ho è che voglio creare un file ZIP in memoria e File zip richiede un oggetto simile a un file.
Soluzione
Probabilmente stai cercando io.BytesIO classe.Funziona esattamente come StringIO tranne per il fatto che supporta i dati binari:
from io import BytesIO
bio = BytesIO(b"some initial binary data: \x00\x01")
StringIO lancerà TypeError:
from io import StringIO
sio = StringIO(b"some initial binary data: \x00\x01")
Altri suggerimenti
Finché non provi a inserire dati Unicode nel tuo file StringIO
e stai attento a NON usarlo cStringIO
dovresti stare bene.
Secondo il StringIO documentazione, finché si mantiene Unicode o 8 bit tutto funziona come previsto.Presumibilmente, StringIO
fa qualcosa di speciale quando qualcuno fa a f.write(u"asdf")
(cosa che ZipFile non fa, per quanto ne so).Comunque;
import zipfile
import StringIO
s = StringIO.StringIO()
z = zipfile.ZipFile(s, "w")
z.write("test.txt")
z.close()
f = file("x.zip", "w")
f.write(s.getvalue())
s.close()
f.close()
funziona esattamente come previsto e non c'è differenza tra il file nell'archivio risultante e il file originale.
Se conosci un caso particolare in cui questo approccio non funziona, sarei molto interessato a saperlo :)
Guarda il pacchetto struct: https://docs.python.org/library/struct.html, consente di interpretare le stringhe come dati binari compressi.
Non sono sicuro che questo risponda completamente alla tua domanda, ma puoi usare struct.unpack() per convertire i dati binari in oggetti Python.
import struct
f = open(filename, "rb")
s = f.read(8)
x, y = struct.unpack(">hl", s)
In questo esempio, ">" indica di leggere big-endian, la "h" legge un breve di 2 byte e la "l" indica un lungo di 4 byte.puoi ovviamente cambiarli in qualunque cosa ti serva per leggere i dati binari...