2008-08-24 18 views
50

En Python puede usar StringIO para un búfer tipo archivo para datos de caracteres. Memory-mapped file básicamente hace algo similar para los datos binarios, pero requiere un archivo que se utiliza como base. ¿Tiene Python un objeto de archivo destinado a datos binarios y solo memoria, equivalente a Java ByteArrayOutputStream?Búfer binario en Python

El caso de uso que tengo es que quiero crear un archivo ZIP en la memoria, y ZipFile requiere un objeto similar a un archivo.

Respuesta

69

Usted probablemente está buscando io.BytesIO clase. Funciona exactamente igual que StringIO excepto que soporta datos binarios:

from io import BytesIO 
bio = BytesIO(b"some initial binary data: \x00\x01") 

StringIO lanzará TypeError:

from io import StringIO 
sio = StringIO(b"some initial binary data: \x00\x01") 
+0

¡Gracias! He estado buscando durante mucho tiempo y solo pude encontrar personas que mencionaran a StringIO, pero este BytesIO es exactamente lo que estoy buscando. – Chad

+0

Esta debería ser la respuesta mejor valorada. – Cacovsky

3

Mire el paquete struct: https://docs.python.org/library/struct.html, le permite interpretar cadenas como datos binarios empaquetados.

No estoy seguro si esto responderá completamente a su pregunta, pero puede usar struct.unpack() para convertir datos binarios a objetos de pitón.

 

import struct 
f = open(filename, "rb") 
s = f.read(8) 
x, y = struct.unpack(">hl", s) 
 

int este ejemplo, el ">" dice a leer bigEndian la "h" se lee en un 2 bytes corta, y la "l" es un de 4 bytes de longitud. obviamente puede cambiarlos a lo que necesite leer de los datos binarios ...

+0

Qué quiere decir hacer algo como esto: http://stackoverflow.com/questions/4239666/getting-bytes-from-unicode-string-in-python – yucer

24

Siempre y cuando no intente poner ningún dato Unicode en su StringIO y tenga cuidado de NO usar cStringIO, debe multa.

De acuerdo con la documentación StringIO, siempre que se mantenga unicode u 8 bits todo funciona como se esperaba. Presumiblemente, StringIO hace algo especial cuando alguien hace un f.write(u"asdf") (que ZipFile no hace, que yo sepa). De todas formas;

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() 

funciona como se esperaba, y no hay diferencia entre el archivo en el archivo resultante y el original.

Si usted sabe de un caso particular en que este enfoque no funciona, yo estaría más interesado en escuchar sobre él :)

+0

¿Por qué cStringIO no funciona aquí? –

+0

Debería funcionar en la mayoría de los casos. No puedo recordar lo que pensé hace unos 3 años, pero una de las razones sería que la entrada al método write() funciona ligeramente diferente (dependiendo del tipo de entrada) entre las dos versiones, y no quería confiar en el interno comportamiento en archivo zip. –

Cuestiones relacionadas