Python: открыть файл в zip-архиве без временного извлечения


84

Как я могу открывать файлы в zip-архиве, не распаковывая их предварительно?

Я использую pygame. Чтобы сэкономить место на диске, я заархивировал все образы. Можно ли загрузить данное изображение прямо из zip-файла? Например: pygame.image.load('zipFile/img_01')


2
Какие файлы изображений? GIF, JPEG и PNG уже сжаты.
hughdbrown

Ответы:


114

Ответ Винсента Повирка не сработает полностью;

import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgfile = archive.open('img_01.png')
...

Вы должны изменить его:

import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgdata = archive.read('img_01.png')
...

Для получения дополнительной информации прочитайте ZipFileдокументацию здесь .


image = pygame.image.load (imgfile, 'img_01.png') TypeError: должна быть строка без нулевых байтов, а не str
user2880847

Объясните, пожалуйста, ваше изменение. read возвращает строку с содержимым файла; open возвращает файловый объект. В документации pygame говорится, что image.load требует имя файла или файловый объект.
Эсме Повирк

@ Винсент Повирк: Спасибо за комментарий. Проблема остается в том, что image.load принимает файловый объект, но не принимает объект zip-файла. К этому нужно как-то адаптироваться. Я тоже не уверен в своем ответе, он еще не элегантен ...
Jellema

21
import io, pygame, zipfile
archive = zipfile.ZipFile('images.zip', 'r')

# read bytes from archive
img_data = archive.read('img_01.png')

# create a pygame-compatible file-like object from the bytes
bytes_io = io.BytesIO(img_data)

img = pygame.image.load(bytes_io)

Я только что пытался понять это для себя и подумал, что это может быть полезно для всех, кто столкнется с этим вопросом в будущем.


8

Теоретически да, это просто вопрос подключения. Zipfile может предоставить вам файловый объект для файла в zip-архиве, а image.load примет объект, подобный файлу. Так должно работать примерно так:

import zipfile
archive = zipfile.ZipFile('images.zip', 'r')
imgfile = archive.open('img_01.png')
try:
    image = pygame.image.load(imgfile, 'img_01.png')
finally:
    imgfile.close()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.