Python: Open file in zip without temporarily extracting it

Question:

How can I open files in a zip archive without extracting them first?

I’m using pygame. To save disk space, I have all the images zipped up.
Is it possible to load a given image directly from the zip file?
For example:
pygame.image.load('zipFile/img_01')

Asked By: user2880847

||

Answers:

In theory, yes, it’s just a matter of plugging things in. Zipfile can give you a file-like object for a file in a zip archive, and image.load will accept a file-like object. So something like this should work:

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()
Answered By: Esme Povirk

Vincent Povirk’s answer won’t work completely;

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

You have to change it in:

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

For details read the ZipFile docs here.

Answered By: Jellema
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)

I was trying to figure this out for myself just now and thought this might be useful for anyone who comes across this question in the future.

Answered By: Brandon

From Python 3.2 onwards it has been possible to use the ZipFile as a context manager:

from zipfile import ZipFile

with ZipFile('images.zip') as zf:
    for file in zf.namelist():
        if not file.endswith('.png'): # optional filtering by filetype
            continue
        with zf.open(file) as f:
            image = pygame.image.load(f, namehint=file)

  • The plus side of using context managers (with statement) is that the files are automatically closed properly.
  • The f can be used like regular file object you would get when using the built-in open().

Links to documentation

Answered By: np8
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.