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')
4 Answers
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.
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.
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() 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 (
withstatement) is that the files are automatically closed properly. - The
fcan be used like regular file object you would get when using the built-in open().