Python: Otwórz plik w formacie zip bez tymczasowego rozpakowywania

84

Jak mogę otwierać pliki w archiwum zip bez wcześniejszego ich rozpakowywania?

Używam pygame. Aby zaoszczędzić miejsce na dysku, wszystkie obrazy zostały spakowane. Czy można załadować dany obraz bezpośrednio z pliku zip? Na przykład: pygame.image.load('zipFile/img_01')

user2880847
źródło
2
Jakie pliki graficzne? GIF, JPEG i PNG są już skompresowane.
hughdbrown

Odpowiedzi:

114

Odpowiedź Vincenta Povirka nie zadziała całkowicie;

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

Musisz to zmienić w:

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

Aby uzyskać szczegółowe informacje, przeczytaj ZipFiledokumentację tutaj .

Jellema
źródło
image = pygame.image.load (imgfile, 'img_01.png') TypeError: musi być ciągiem bez bajtów null, a nie str
user2880847
Proszę wyjaśnij swoją zmianę. read zwraca ciąg znaków z zawartością pliku; open zwraca obiekt podobny do pliku. Dokumentacja pygame mówi, że image.load potrzebuje nazwy pliku lub obiektu podobnego do pliku.
Esme Povirk
@Vincent Povirk: Dziękuję za komentarz. Problemem pozostaje to, że image.load akceptuje obiekt podobny do pliku, ale nie akceptuje obiektu plik-zip. Musisz jakoś się do tego dostosować. Nie jestem przekonany do mojej odpowiedzi, nie jest jeszcze elegancka ...
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)

Próbowałem to sobie wymyślić właśnie teraz i pomyślałem, że może to być przydatne dla każdego, kto zetknie się z tym pytaniem w przyszłości.

Brandon
źródło
8

Teoretycznie tak, to tylko kwestia podłączenia rzeczy. Zipfile może dać ci obiekt podobny do pliku dla pliku w archiwum zip, a image.load zaakceptuje obiekt podobny do pliku. Więc coś takiego powinno działać:

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()
Esme Povirk
źródło