Двоичный буфер в Python
Вопрос
В Python вы можете использовать СтрокаIO для файлового буфера для символьных данных. Файл, отображаемый в памяти в основном делает то же самое для двоичных данных, но для этого требуется файл, который используется в качестве основы.Есть ли в Python файловый объект, предназначенный для двоичных данных и занимающий только память, что эквивалентно объекту Java? БайтмассивВыходной поток?
У меня есть вариант использования: я хочу создать ZIP-файл в памяти и Zip-файл требуется файлоподобный объект.
Решение
Вы, вероятно, ищете 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")
Другие советы
Пока вы не пытаетесь поместить какие-либо данные Юникода в свой StringIO
и вы стараетесь НЕ использовать cStringIO
с тобой должно быть все в порядке.
Согласно СтрокаIO документации, пока вы придерживаетесь юникода или 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()
работает так, как ожидалось, и нет никакой разницы между файлом в полученном архиве и исходным файлом.
Если вам известен конкретный случай, когда этот подход не работает, мне было бы очень интересно об этом узнать :)
Посмотрите на пакет структуры: 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)
В этом примере «>» указывает на необходимость чтения с прямым порядком байтов, «h» читает 2-байтовый короткий фрагмент, а «l» — 4-байтовый.вы, очевидно, можете изменить их на все, что вам нужно для считывания двоичных данных...