Сведения о вопросе

krutoi

10:46, 1st August, 2020

Теги

python   binary   io   buffer    

Двоичный буфер в Python

Просмотров: 441   Ответов: 3

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

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



  Сведения об ответе

SILA

16:22, 28th August, 2020

Вы, вероятно, ищете 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")


  Сведения об ответе

9090

21:56, 2nd August, 2020

До тех пор, пока вы не пытаетесь поместить какие-либо данные юникода в свой StringIO , и вы осторожны NOT, чтобы использовать 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()

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

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


  Сведения об ответе

fo_I_K

08:29, 13th August, 2020

Посмотрите на пакет 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)

в этом примере символ " > " указывает на чтение Биг-энда, а символ "h"-на 2-байтовый короткий, а символ "l"-на 4-байтовый длинный. очевидно, что вы можете изменить их на все, что вам нужно, чтобы прочитать из двоичных данных...


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться