Python: Open file in zip without temporarily extracting it

PythonZip

Python Problem Overview


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')

Python Solutions


Solution 1 - Python

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.

Solution 2 - Python

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.

Solution 3 - Python

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()

Solution 4 - Python

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().

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2880847View Question on Stackoverflow
Solution 1 - PythonJellemaView Answer on Stackoverflow
Solution 2 - PythonBrandonView Answer on Stackoverflow
Solution 3 - PythonEsme PovirkView Answer on Stackoverflow
Solution 4 - Pythonnp8View Answer on Stackoverflow