2008-08-24 14 views
50

В Python вы можете использовать StringIO для файлового буфера для символьных данных. Memory-mapped file в основном делает аналогичную вещь для двоичных данных, но для этого требуется файл, который используется в качестве основы. У Python есть объект файла, который предназначен для двоичных данных и является только памятью, эквивалентной ByteArrayOutputStream Java?Бинарный буфер в Python

В этом случае я хочу создать ZIP-файл в памяти, а ZipFile требует файлового объекта.

ответ

69

Вы, вероятно, ищете io.BytesIO класса. Это работает точно так же, как StringIO за исключением того, что он поддерживает двоичные данные:

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

StringIO выбросит TypeError:

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

Посмотрите на пакет struct: https://docs.python.org/library/struct.html, он позволяет интерпретировать строки как упакованные двоичные данные.

Не уверен, что это полностью ответит на ваш вопрос, но вы можете использовать struct.unpack() для преобразования двоичных данных в объекты python.

 

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

INT в этом примере, то «>» говорит читать тупоконечник «Н» читает 2-байтовый короткие, и «л» для 4-байта длиной. вы можете, очевидно, изменить их на все, что вам нужно, чтобы читать из двоичных данных ...

+0

ли вы имеете в виду, чтобы сделать что-то вроде этого: http://stackoverflow.com/questions/4239666/getting-bytes-from-unicode-string-in-python – yucer 2016-12-27 11:18:59

24

Пока вы не пытаетесь поместить какие-либо данные в unicode в свой StringIO, и вы будете осторожны, НЕ используйте cStringIO, вы должны быть хорошо.

В соответствии с документацией StringIO, при условии, что вы сохраните либо в Юникоде, либо в 8 бит, все будет работать так, как ожидалось. Предположительно, StringIO делает что-то особенное, когда кто-то делает f.write(u"asdf") (которого ZipFile не делает, насколько мне известно). Так или иначе;

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

работает так, как ожидалось, и нет никакого различия между файлом в полученном архиве и исходном файле.

Если вы знаете о конкретном случае, когда этот подход не работает, я бы очень интересно услышать об этом :)

+0

Почему cStringIO здесь не работает? – 2011-05-10 20:59:36

+0

Он должен работать в большинстве случаев. Я не могу вспомнить, что я думал около 3 лет назад, но одна из причин заключалась в том, что вход для метода write() работает несколько иначе (в зависимости от типа ввода) между двумя версиями, и я не хотел полагаться на внутренние поведение в zipfile. – 2011-05-11 20:46:21