Передайте объект io.BytesIO в gzip.GzipFile и запишите в GzipFile

Я в основном хочу сделать именно то, что в документации gzip.GzipFile:

Вызов метода close() объекта GzipFile не закрывает fileobj, так как вы можете добавить больше материала после сжатых данных. Это также позволяет вам передавать объект io.BytesIO, открытый для записи, как fileobj, и извлекать полученный буфер памяти, используя метод getvalue() объекта io.BytesIO.

С обычным файловым объектом все работает как положено.

>>> import gzip
>>> fileobj = open("test", "wb")
>>> fileobj.writable()
True
>>> gzipfile = gzip.GzipFile(fileobj=fileobj)
>>> gzipfile.writable()
True

Но я не могу получить доступный для записи gzip.GzipFile объект при прохождении io.BytesIO объект.

>>> import io
>>> bytesbuffer = io.BytesIO()
>>> bytesbuffer.writable()
True
>>> gzipfile = gzip.GzipFile(fileobj=bytesbuffer)
>>> gzipfile.writable()
False

Должен ли я открыть io.BytesIO явный для написания, и как бы я это сделал? Или есть разница между файловым объектом, возвращаемым open(filename, "wb") и объект, возвращенный io.BytesIO() Я не думал о?

1 ответ

Решение

Да, вам нужно явно установить GzipFile режим для 'w'; в противном случае он попытался бы взять режим из объекта файла, но BytesIO объект не имеет .mode атрибут:

>>> import io
>>> io.BytesIO().mode
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: '_io.BytesIO' object has no attribute 'mode'

Просто укажите режим явно:

gzipfile = gzip.GzipFile(fileobj=fileobj, mode='w')

Демо-версия:

>>> import gzip
>>> gzip.GzipFile(fileobj=io.BytesIO(), mode='w').writable()
True

В принципе BytesIO объект открыт в 'w+b' режим, но GzipFile будет смотреть только на первый символ режима файла.

Другие вопросы по тегам